天天看点

Spring Boot 进阶-详解Mybatis数据层原理(一)

作者:架构师面试宝典
Spring Boot 进阶-详解Mybatis数据层原理(一)

Mybatis作为一款比较优秀的持久层框架,支持了定制化SQL开发、存储过程以及高级映射等功能,几乎避免了所有的JDBC代码和手动设置参数获取结果的操作,可以通过简单的XML文件或者是使用主机的的方式来配置映射关系,将接口与Java的POJO对象进行映射。实现了简单高效的持久层开发。下面我们就来一起详细了解一下关于MyBatis相关的知识。

简述

MyBatis的前身是Apache的开源项目iBatis,2010年的时候改名成Mybatis。IBatis是一个Java持久层框架,提供了SQL Map 以及Data Access Object等功能。

在Mybatis中采用面向对象编程的方式对数据库进行CRUD的操作,这样简化了通过映射关系来进行数据库操作的方式。通过支持XML配置文件扫描和注解的方式来实现对于SQL语句的映射执行以及结果反馈,极大的提高了ORM的执行效率。

早起的ORM框架例如Hibernate等,提供了从数据库到POJO对象的全套映射,开发者定义好了POJO对象与数据库表结构的关联之后,就可以通过Hibernate提供的方法进行持久化的操作,并且不需要对SQL语句有太多的掌握,Hibernate框架会更具具体的调用操作来实现SQL与JDBC的操作关系并且执行SQL映射结果。

这样的操作往往带来的问题就是再有些复杂情况下,Hibernate的查询执行效率就有点太低下了。当面对一些复杂查询的时候Hibernate就不再适用了。当然我们可以使用JDBC操作执行对数据库进行操作,但是这样的操作就会带来很多的性能上的损耗。

相比较于Hibernate这种全自动化的ROM框架Mybatis被称为是半自动的ORM框架,为什么这么说呢?

相比较Hibernate,Mybatis通过XML以及注解等方式提供了用户自定义的SQL语句,只有执行了对应的语句才会有对应的结果进行映射,这个时候这个操作是由程序员来完成的。而对于编写好的SQL语句以及映射关系等,又是由框架自动进行封装映射的。所以被称为是半自动的ORM框架。

Mybatis框架的组成

如下图所示,图片来源网络。我们对每个层进行一个简单的介绍。

Spring Boot 进阶-详解Mybatis数据层原理(一)

接口层

首先Mybatis是用来封装对于数据库的访问操作,而对于数据库的访问操作,一般都是通过接口层来进行的。而接口层一般就是由一个会话来进行调用操作。这个时候就需要我们了解一下SqlSession对象。

在我们进行Mybatis配置的时候会在配置文件中添加如下的一个配置Bean

@Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
    {
        String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
        String mapperLocations = env.getProperty("mybatis.mapperLocations");
        String configLocation = env.getProperty("mybatis.configLocation");
        typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
        VFS.addImplClass(SpringBootVFS.class);

        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
        sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
        sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
        return sessionFactory.getObject();
    }           

这里就是用来给容器中生成SqlSession的工厂类,而我们需要的SqlSession则是在org.apache.ibatis.session.SqlSession包下的接口。在这个接口中提供了我们操作数据库所有的方法。

Spring Boot 进阶-详解Mybatis数据层原理(一)

总列表上看,SqlSession中提供了对于数据库的基本的CRUD操作。同时还提供了一些事务回滚相关的操作。以及数据库连接、配置、缓存、Mapper映射等相关配置操作的API。我们可以根据具体的配置通过SqlSessionFactory来生成对应的SqlSession来进行对数据库的操作。

根据上面的介绍在SqlSession的建立过程中Configuration是比较关键的类。在这个类中定义了所有关于SqlSession配置的相关属性信息,而只有了解了这些属性信息才能更好的使用Mybatis相关的配置。在Mybatis中提供了对SqlSession的默认实现DefaultSqlSession,并且也提供了对于DefaultSqlSession的默认实现工厂DefaultSqlSessionFactory,当然除了可以静态的通过配置文件进行配置之外,我们还可通过上面代码中所展示那个样来实现动态的配置。

数据处理层

当项目启动的时候,Mybatis会去加载并且解析两种配置。

  • SQLMapConfig.xml
  • Mapper.xml

其中SQLMapConfig 配置是在XMLConfigBuilder类中进行解析的,而Mapper配置文件则是在XMLMapperBuilder即解析完成,从两个类的名称中可以知道一个是用来解析关于Mybatis的的配置,一个是用来解析MapperSQL映射相关的配置,而这些配置都是可以通过注解的方式来进行设置的。如下图所示。

Spring Boot 进阶-详解Mybatis数据层原理(一)

图片来源网络

XMLMapperBuilder将SQL语句进行解析之后委托给了XMLStatementBuilder来进行对于SQL语句的解析操作。而在XMLStatementBuilder有一个parseStatementNode的方法,这个方法中就是对Mapper文件进行了解析。代码如下,这里只是截取了一部分代码,其中有我们熟悉的parameterMap、resultType、resultMap等属性感兴趣的读者可以阅读源码,加深影响。

// 部分代码
		SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
    StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
    Integer fetchSize = context.getIntAttribute("fetchSize");
    Integer timeout = context.getIntAttribute("timeout");
    String parameterMap = context.getStringAttribute("parameterMap");
    String resultType = context.getStringAttribute("resultType");
    Class<?> resultTypeClass = resolveClass(resultType);
    String resultMap = context.getStringAttribute("resultMap");
    String resultSetType = context.getStringAttribute("resultSetType");
    ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
    if (resultSetTypeEnum == null) {
      resultSetTypeEnum = configuration.getDefaultResultSetType();
    }           

总结

到目前为止我们据介绍的都是关于需要程序员手动配置才能执行的部分的介绍,还有一些关于日志、IO、反射等相关的内容我们留在下一篇文章中进行介绍。希望大家可以多多关注。后续会为大家带来更多的干货内容。

继续阅读