前言:
研究Mybatis的二级缓存需要去扒拉下人家的源代码,研究Mybatis提供的官方jar包;
研究方向万变不离其宗,就算不去看人家的源代码,我们猜一猜也能猜到个大概,大概是用map缓存,
然后用整串的sql+参数作为key,然后查询结果作为value,至于是不是我们可以后面再瞅瞅。
Mybatis源代码开启
我们主要看两块儿,一块儿是Cache,一块儿是CacheIngExecutor
Cache:数据结构的定义
数据结构分析
核心接口:Cache
贴出来就是让你看看,里面没啥干货
真正的数据结构来了:PerpetualCache
你看,是不是验证了我的设想,就是用了一个map来存储
然后我们会发现cache包下面还有一个东西叫decorators
他的实现方式有很多种,很好奇,为毛用这么多的实现,其实实现这么多只是使用了一个装饰者模式,目的是为了给缓存加上各种装饰
decorators,单词的意思叫装饰,很自然的就会想到设计模式里的装饰者模式,如果读者不了解装饰者模式的可以先去了解下然后往下阅读
FifoCache
LoggingCache
LruCache
ScheduledCache
SerializedCache
SoftCache
SynchronizedCache
TransactionalCache
WeakCache
BlockingCache
我们看到LogginCache,猜想下就是日志,SoftCache 软引用 WeakCache 弱引用 FifoCahce 先进先出,一看就是给缓存加上了一些功能,就是通过装饰者模式给缓存加上各种不同的自定义功能。
可以简单的看下其中某一个装饰者
可以看到都是里面包含了一个Cache,然后层次的递进引用,引用到最后一波就是PerpetualCache,反过来可以看到拿最基础的PerpetualCache一层一层的给他包裹新功能,这就是装饰者模式的典型的应用场景
,数据结构到此基本上结束了。
CachingExecutor:缓存调用
核心代码就是下面的这段,建议大家自己打个断点就能理解的更形象一点,我这边文字描述的再详细毕竟只是我自己的理解
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
// 将mapper.xml信息加载后形成Cache
Cache cache = ms.getCache();
if (cache != null) {
// 判断是否需要刷新缓存,比如插入等会破坏缓存的行为或者缓存时间过期等都需要刷新
flushCacheIfRequired(ms);
//判断缓存是否开启 对应mapper中的cache标签是否配置
if (ms.isUseCache() && resultHandler == null) {
//这段可以跳过,是一种校验,感兴趣的可以去搜搜,不影响主干
ensureNoOutParams(ms, parameterObject, boundSql);
@SuppressWarnings("unchecked")
//获取缓存的结果集
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
//为空那就需要放到缓存里了
list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
// 委托模式,交给SimpleExecutor等实现类去实现方法 如果没有缓存那就得去自己跑了
return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
简单的调用基本上就结束了,大道至简不是么,恭喜毕业,剩下的细节大家自己带铁锹挖,只是领你入门。
Mybatis二级缓存使用的很多注意事项:
1 基础Bean必须要实现序列化接口
2 查询条件要谨慎,如果不消息用了一个动态的参数,比如当前时间,那么就不适合,因为实时改变,key一直变,这时候你加了缓存,性能会变差
总结:如果基础bean没有实现序列化接口或者是第二种情况,缓存均不会生效,这时候你开启了缓存,但是缓存没卵用,性能反而会降低。