通过源码分析MyBatis的缓存

Posted 称雄

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过源码分析MyBatis的缓存相关的知识,希望对你有一定的参考价值。

  看了通过源码分析MyBatis的缓存这篇文章后,自己跟着源码过了一遍,对mybatis的一级缓存和二级缓存有了更清楚的认识。

  一级缓存是SqlSession级别的,同一个sqlSession在第二次执行一个相同参数的select语句并且第一次执行后没有对数据进行更新,就会直接从缓存取值,而不再进行查找。通过阅读源码了解了这个过程,首先org.apache.ibatis.session.defaults.DefaultSqlSession.select(String, Object, RowBounds, ResultHandler)方法会调用executor.query(ms, wrapCollection(parameter), rowBounds, handler),然后分析executor的类型,在org.apache.ibatis.session.defaults.DefaultSqlSessionFactory类中,openSessionFromDataSource(ExecutorType, TransactionIsolationLevel, boolean)方法的Executor executor = configuration.newExecutor(tx, execType) 语句实例化executor,代码如下,在SqlMapConfig.xml中cacheEnabled默认为true,即一级缓存默认开启,故executor为CachingExecutor类型。

/*     */   public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
/* 540 */     executorType = executorType == null ? defaultExecutorType : executorType;
/* 541 */     executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
/*     */     Executor executor;
/* 543 */     if (ExecutorType.BATCH == executorType) {
/* 544 */       executor = new BatchExecutor(this, transaction); } else { Executor executor;
/* 545 */       if (ExecutorType.REUSE == executorType) {
/* 546 */         executor = new ReuseExecutor(this, transaction);
/*     */       } else
/* 548 */         executor = new SimpleExecutor(this, transaction);
/*     */     }
/* 550 */     if (cacheEnabled) {
/* 551 */       executor = new CachingExecutor(executor);
/*     */     }
/* 553 */     Executor executor = (Executor)interceptorChain.pluginAll(executor);
/* 554 */     return executor;
/*     */   }
/*     */   

 

  在org.apache.ibatis.executor.CachingExecutor.query(MappedStatement, Object, RowBounds, ResultHandler, CacheKey, BoundSql)方法中首先获取二级缓存,由于二级缓存为空,执行该语句

return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

  delegate对象为org.apache.ibatis.executor.SimpleExecutor类型,继承自org.apache.ibatis.executor.BaseExecutor类,query方法如下

BaseExecutor的属性localCache是个PerpetualCache类型的实例,PerpetualCache类是实现了MyBatis的Cache缓存接口的实现类之一,内部有个Map<object, object>类型的属性用来存储缓存数据。 这个localCache的类型在BaseExecutor内部是写死的。 这个localCache就是一级缓存!

 

在数据更改时会清空缓存。

 

 

 

二级缓存是基于namespace的,必须在sqlSession提交或关闭才会生效。需要在mapper配置文件加上<cache />。

以上是关于通过源码分析MyBatis的缓存的主要内容,如果未能解决你的问题,请参考以下文章

通过源码分析MyBatis的缓存

肝了一夜的源码,终于可以通过源码分析MyBatis的缓存了!

mybatis源码分析之05一级缓存

mybatis源码分析之06二级缓存

MaBatis学习---源码分析MyBatis缓存原理

mybatis关于二级缓存的配置及源码分析