MyBatis辅助功能点一: cache源码初体验

  分析缓存源码首先得找到缓存操作的入口:前面已经分析,sqlsesion.close()仅对一级缓存有影响,而update等对一/二级缓存均有影响。那从session为入口分析一级缓存,从mapper分析二级缓存。

一级缓存

  跟踪调试仅使用一级缓存的代码,调试信息发现,MyBatis辅助功能点一: cache源码初体验 ,即可知SimpleExectutor或其上级父类中对一级缓存进行处理,跟踪调试信息,可得如下调用链(BaseExecutor为SimpleExecutor父类):MyBatis辅助功能点一: cache源码初体验

  一级缓存功能由BaseExecutor类实现,即意味着每个实际执行器都具有这一级的功能。

  MyBatis辅助功能点一: cache源码初体验

  CacheUML图:从图中可见,cache基本操作如上图分析一致,由PerpetualCache类提供。装饰器包中提供增强功能的cache执行器。所谓缓存本质就是一个Map对象。

  MyBatis辅助功能点一: cache源码初体验

  那么其具体应用逻辑为何?查看源码如下:

MyBatis辅助功能点一: cache源码初体验

   从源码分析可得:如果设置了每次查询都清缓存,那么每次查询清缓存。同时查询之前判断localCache中是否有当前查询statement.id的相应数据,如果有则直接从一级缓存中获取结果,否则进行查询数据库的操作。

二级缓存

  二级缓存的作用范围是一个命名空间(即一个映射文件),而且可以实现多个命名空间共享一个缓存。跟踪二级缓存,其建立在mapper配置文件解析过程中即建立,而不是在opensession中。

MyBatis辅助功能点一: cache源码初体验

 

   二级缓存默认开启,如取消采用如下配置:

  <settings>
   <setting name="cacheEnabled" value="false"/>
  </settings>
  注解方式在mapper接口中使用如下注解,二级缓存生效,否则开启亦不生效。同理在mapper.xml文件中也需配置<cache></cache>表示二级缓存生效

  通过注解MyBatis辅助功能点一: cache源码初体验开启二级缓存,查看注解源码

 

   MyBatis辅助功能点一: cache源码初体验

  可知默认使用PerpetualCache的实现,通过implementation属性,可以配置用户需要使用的第三方或自定义缓存,比如redis。

  那二级缓存是如何工作的?我们开启二级缓存通过调试查看源码(如下):

  MyBatis辅助功能点一: cache源码初体验

 

   可知CachingExecutor中首先查询二级缓存,如果查询结果为空则业务逻辑有simpleExecutor处理即一级缓存的使用逻辑。

  开篇提到,sqlSession.close仅对一级缓存清空二级缓存无影响,以及update等操作对一二级缓存均清空,那么通过close和update源码分别来证实:

MyBatis辅助功能点一: cache源码初体验

 

   分析CachingExecutor中close的业务逻辑:

  MyBatis辅助功能点一: cache源码初体验

 

   首先处理二级缓存rollback或者commit,再处理一级缓存赋值null。所以close操作会清空一级缓存,二级缓存强制回退或者提交数据。

MyBatis辅助功能点一: cache源码初体验

   分析CachingExecutor中update的业务逻辑,显然与close方法不同,如下:MyBatis辅助功能点一: cache源码初体验

 

   在上面分析过程中都遇到了CachingExecutor的一个属性,tcm——啥玩意?TransactionalCacheManager

MyBatis辅助功能点一: cache源码初体验

 

   MyBatis将Cache,TransactionalCache做了映射,而不是和一级缓存保存一致,直接使用,这是为什么呢?下面附源码两张:

  MyBatis辅助功能点一: cache源码初体验

  MyBatis辅助功能点一: cache源码初体验

 

   第一张图说明一级缓存直接在executor中活动,即作用范围为session;第二张图说明二级缓存在MappedStatement中活动,作用范围跨session了。同样证实了开篇提到的cache作用范围。也因为二级缓存的作用范围跨session,可以同时被多个session同时获取就出现了线程安全的问题,导致脏读问题。为了解决这一问题,就有了TransactionalCache及其Manager——就是tcm对应类。

  MyBatis辅助功能点一: cache源码初体验

 

   从其类图中,可以直观的发现其增加了读写锁相关的功能。

MyBatis辅助功能点一: cache源码初体验

上一篇:Ubuntu


下一篇:极坐标三维插值问题