Mybatis

MyBatis是支持普通SQL查询和高级映射的优秀持久层框架。它消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录。

SqlSessionFactory

MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心,它是SqlSessionFactoryBuilder对象通过配置文件Configuration类实例中来构建SqlSessionFactory对象,在使用时常通过Spring来集成和整合,下面是SqlSessionFactory的基本配置文件。
img
可以看出,sqlSessionFactory被注册为spring容器中的bean,配置了使用的数据源,还有mybatis配置文件的位置、mapper xml文件的位置。sqlSessionFactory主要用来产生sqlSession,而sqlSession在Spring中使用了它的实现类sqlSessionTemplate,还定义了mapper接口的包路径,这里配置的MapperScannerConfigurer会将basePackage里的mapper接口注册为spring容器中的bean,并同时注入sqlSessionTemplate到mapper接口对象中,否则需要单独定义每一个mapper接口的bean。具体的Spring配置如下:
img
由上面分析可以看出,sqlSessionFactory的产生流程如下:首先sqlSessionFactoryBean根据mybatis配置文件构造出configuration对象,.然后通过sqlSessionFactoryBuilder的build方法构造出一个sqlSessionFactory实例,sqlSession的产生是通过sqlSessionFactory创建了它的实现类sqlSessionTemplate。

Mapper

下面继续分析Mybatis中mapper接口,通常在程序中我们通过如下方式使用mapper:
img
在上面的spring配置中,将basePackage里的mapper接口注册为spring容器中的bean,在session调用getMapper时,扫描basePackage内的所有mapper接口并将这些bean设置为MapperFactoryBean.class,还添加了sqlSessionTemplate对象的引用。所以mapper对象由MapperFactoryBean来创建,在调用SqlSessionTemplate.getMapper时会调用MapperRegistry的getMapper方法,进而又通过了MapperProxyFactory对象创建mapper对象,MapperRegistry还记录了mapper接口和MapperProxyFactory对象的映射关系。MapperProxy类实现了InvocationHandler接口,mapper对象是其实是实现了对应mapper接口的动态代理对象,对mapper接口方法的调用都会调用代理对象的invoke方法,mapper对象的创建流程如下图:
img
所以mybatis整合spring时,先通过SqlSessionFactoryBean创建了SqlSessionFactory,SqlSessionFactory创建了sqlSession,然后通过MapperFactoryBean生成了mapper对象,mapper对象的创建使用了java动态代理,mapper接口方法的调用都在代理对象的invoke方法中完成。

Mybatis的SQL执行

最后我们分析一条sql语句的执行过程:
img
在getMapper方法得到mapper对象后,调用接口相关的语句时,经过上面的分析会调用MapperProxy对象的invoke方法(每一个MapperProxy对应一个dao接口),然后会触发MapperMethod调用excute方法,该方法会根据根据类型去选择到底执行sqlSession中的哪个方法(insert、update、delete、select),然后执行相应的SqlSession的CRUD方法,之后会执行Excutor的doQueryQ方法,最后一步一步的封装最终通过PreparedStatement处理相关sql语句,然后执行结果逐步返回给sqlsession。
最后在Mapper的的映射文件…Maper.xml文件中有很多动态sql语句,大大减少了sql语句拼接的复杂度,主要有insert、update、delete、select、if、choose、when、otherwise、where、set、foreach、trim等标签,具体的使用可参考帮助文档。

MyBatis的动态sql语句http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html。

谢谢大佬的打赏!