通过源码分析MyBatis的缓存

本文详细分析了MyBatis的一级缓存和二级缓存工作原理,通过源码解读,阐述了SqlSession级别的缓存如何在相同的查询条件下避免重复数据库操作,以及基于namespace的二级缓存如何在提交或关闭时生效。

  看了通过源码分析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 />。

转载于:https://www.cnblogs.com/csdeblog/p/9740769.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值