入门
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
我们就可以通过 SqlSessionFactory 获得 SqlSession 的实例。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
|
|
新版本更推荐使用对于给定语句能够合理描述参数和返回值的接口(Mapper)
|
|
源码解读
第一种写法
目前公司采用这种写法,在DAO层调用SqlSessionTemplate的方法。好处是可以将一些简单的逻辑写在dao实现类,比如设置创建、更新信息,对sql结果简单的处理。
|
|
SqlSessionTemplate 是 MyBatis-Spring 的核心。 这个类负责管理 MyBatis 的 SqlSession, 调用 MyBatis 的 SQL 方法, 翻译异常。 SqlSessionTemplate 是线程安全的, 可以被多个 DAO 所共享使用。
当调用 SQL 方法时, 包含从映射器 getMapper()方法返回的方法, SqlSessionTemplate 将会保证使用的 SqlSession 是和当前 Spring 的事务相关的。此外,它管理 session 的生命 周期,包含必要的关闭,提交或回滚操作。
SqlSessionTemplate中的属性SqlSession采用了动态代理的方式,在执行sqlSessionProxy的方法时,会被SqlSessionInterceptor拦截到。在该拦截器的invoke方法中,会从Spring事务管理器获取sqlsession,管理sqlsession的生命周期。
|
|
继续通过断点跟踪,实际调用的还是SqlSession的一个实现类DefaultSqlSession,其中属性executor默认为CachingExecutor,Executor负责执行数据库操作。
|
|
CachingExecutor先尝试从内存中获取数据,若没有的话通过代理调用其它Executor实现类的query方法,这里应是mybatis二级缓存,实际没有用过不做研究了。
|
|
BaseExecutor有三个子类,分别对应于SqlSessionTemplate中ExecutorType的3个枚举类型。在公司项目中,指定了ExecutorType为REUSE,根据sql缓存了jdbc的statement
|
|
BaseExecutor有个属性PerpetualCache是mybatis一级缓存,本质是一个HashMap,Key根据StatementId(com.jh.dao.BlogDao.selectBlog)、RowBounds分页的参数(limit&offset)、sql语句(select * from blog where id = ?)、查询条件(1)这几个条件生成。
|
|
update操作(包括update(),delete(),insert())在执行到BaseExecutor.update()时清空一级缓存,再执行数据库查询操作。
第二种写法
|
|
用到了动态代理,Mapper接口实际调用MapperProxy.invoke,底层同样调用SqlSession的方法
|
|
之后的流程与第一种写法一样。
小结
本文只是简单记录一下mybatis大体流程,之后如有机会将深入研究具体细节。
mybatis源码中用到的动态代理和一些设计模式,值得进一步学习。