1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Mybatis源码学习笔记之Mybatis二级缓存

Mybatis源码学习笔记之Mybatis二级缓存

时间:2021-09-29 12:11:10

相关推荐

Mybatis源码学习笔记之Mybatis二级缓存

简介

Mybatis一级缓存是会话级的缓存,而二级缓存则是应用级别的缓存,默认关闭,二级缓存使用不慎可能会导致脏读。

开启方式(SpringBoot+Mybatis)

application.properties添加配置

mybatis.configuration.cache-enabled=true

在mapper的xml文件中的namespace中加上

<cache></cache>

为了方便看到效果 ,application.properties设置日志级别为debug

.qs.birp.dao=debugmybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

先测试调用一次SQL ,再次调用时可以缓存命中。

Creating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3563659a] was not registered for synchronization because synchronization is not activeCache Hit Ratio [com.qs.birp.dao.EquTAufkDao]: 0.3333333333333333Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3563659a]Creating a new SqlSessionSqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d18d986] was not registered for synchronization because synchronization is not activeCache Hit Ratio [com.qs.birp.dao.EquTAufkDao]: 0.5Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d18d986]

命中条件

和一级缓存不同,二级缓存在事务提交和会话关闭后才会写入(在会话和二级缓存间会有一个事务缓存管理器TransactionalCacheManager,会话期间查询的数据会放到管理器的暂存区TransactionalCache,当事务提交后才会写入到指定的二级缓存区域),当执行数据库update操作时会清空该namespace下的缓存。

相同的statement id相同的Sql与参数查询结果分页条件相同没有使用ResultHandler来自定义返回数据没有配置UseCache=false 来关闭指定查询的缓存没有配置FlushCache=true 来清空缓存在调用存储过程中不能使用出参,即Parameter中mode=out|inout

源码解析

源码位置:org.apache.ibatis.executor.CachingExecutor.java 这里面比较关键的代码是List list = (List) tcm.getObject(cache, key);

@Overridepublic <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {Cache cache = ms.getCache();if (cache != null) {flushCacheIfRequired(ms);if (ms.isUseCache() && resultHandler == null) {ensureNoOutParams(ms, boundSql);@SuppressWarnings("unchecked")List<E> list = (List<E>) tcm.getObject(cache, key);if (list == null) {list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);tcm.putObject(cache, key, list); // issue #578 and #116}return list;}}return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);}

Mybatis源码里面二级缓存使用装饰器的设计模式,装饰器在org.apache.ibatis.cache.decorators包下面。

SynchronizedCache 同步锁,用于保证对指定缓存区的操作都是同步的

LoggingCache 统计器,记录缓存命中率

BlockingCache 阻塞器,基于key加锁,防止缓存穿透

ScheduledCache 时效检查,用于验证缓存有效器,并清除无效数据

LruCache 溢出算法,最近最少使用算法,淘汰闲置最久的缓存。

FifoCache 溢出算法,淘汰加入时间最久的缓存

WeakCache 溢出算法,基于java弱引用规则淘汰缓存

SoftCache 溢出算法,基于java软引用规则淘汰缓存

PerpetualCache 实际存储,内部采用HashMap进行存储。

注意事项

只能在【只有单表操作】的表上使用缓存

不只是要保证这个表在整个系统中只有单表操作,而且和该表有关的全部操作必须全部在一个namespace下。在可以保证查询远远大于insert,update,delete操作的情况下使用缓存

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。