本文转自:https://blog.csdn.net/luanlouis/article/details/41408341
二级缓存是Application应用级别的缓存,它的是生命周期很长,跟Application的声明周期一样,也就是说它的作用范围是整个Application应用。
1、二级是mapper级别的缓存。使用二级缓存时,多个sqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储。
相比一级缓存SqlSession,二级缓存的范围更大,多个SqlSession可以公用二级缓存,二级缓存是夸SqlSession的。
2、二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace。不同的SqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕将数据库中查询的数据写到缓存(内存),第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。
3、MyBatis默认没有开启二级缓存,需要在setting全局参数中配置开启二级缓存:
解释:创建了一个LRU缓存,每隔60秒刷新,最大存储512个对象,而且返回对象被认为是只读的。
flushInterval:刷新间隔
size:缓存数据,默认1024
readOnly:只读。
eviction:收回策略,默认LRU。
LRU:最近最少使用的策略,移除最长时间不被使用的对象。
FIFO:先进先出策略,按对象进入缓存的顺序来移除他们。
SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象。
WEAK:弱引用策略,更积极地移除基于垃圾回收器状态和弱引用规则的对象。
如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章。
如果用户配置了"cacheEnabled=true",那么MyBatis在为SqlSession对象创建Executor对象时,会对Executor对象加上一个装饰者:CachingExecutor,这时SqlSession使用CachingExecutor对象来完成操作请求。
CachingExecutor对于查询请求,会先判断该查询请求在Application级别的二级缓存中是否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的Executor对象来完成查询操作,之后CachingExecutor会将真正Executor返回的查询结果放置到缓存中,然后在返回给用户。
CachingExecutor是Executor的装饰者,以增强Executor的功能,使其具有缓存查询的功能,这里用到了设计模式中的装饰者模式,
CachingExecutor和Executor的接口的关系如下类图所示:
MyBatis并不是简单地对整个Application就只有一个Cache缓存对象,它将缓存划分的更细,即是Mapper级别的,即每一个Mapper都可以拥有一个Cache对象,具体如下:
a.为每一个Mapper分配一个Cache缓存对象(使用
节点配置); b.多个Mapper共用一个Cache缓存对象(使用
节点配置);
如果你想让多个Mapper公用一个Cache的话,你可以使用
MyBatis对二级缓存的支持粒度很细,它会指定某一条查询语句是否使用二级缓存。
虽然在Mapper中配置了
总之,要想使某条Select查询支持二级缓存,你需要保证:
1. MyBatis支持二级缓存的总开关:全局配置变量参数 cacheEnabled=true
2. 该select语句所在的Mapper,配置了
或 节点,并且有效 3. 该select语句的参数 useCache=true
请注意,如果你的MyBatis使用了二级缓存,并且你的Mapper和select语句也配置使用了二级缓存,那么在执行select查询的时候,MyBatis会先从二级缓存中取输入,其次才是一级缓存,即MyBatis查询数据的顺序是:
二级缓存 ———> 一级缓存——> 数据库
MyBatis对二级缓存的设计非常灵活,它自己内部实现了一系列的Cache缓存实现类,并提供了各种缓存刷新策略如LRU,FIFO等等;另外,MyBatis还允许用户自定义Cache接口实现,用户是需要实现org.apache.ibatis.cache.Cache接口,然后将Cache实现类配置在
1.MyBatis自身提供的缓存实现;
2. 用户自定义的Cache接口实现;
3.跟第三方内存缓存库的集成;
MyBatis自身提供了丰富的,并且功能强大的二级缓存的实现,它拥有一系列的Cache接口装饰者,可以满足各种对缓存操作和更新的策略。
MyBatis定义了大量的Cache的装饰器来增强Cache缓存的功能,如下类图所示。
对于每个Cache而言,都有一个容量限制,MyBatis各供了各种策略来对Cache缓存的容量进行控制,以及对Cache中的数据进行刷新和置换。MyBatis主要提供了以下几个刷新和置换策略:
LRU:(Least Recently Used),最近最少使用算法,即如果缓存中容量已经满了,会将缓存中最近做少被使用的缓存记录清除掉,然后添加新的记录;
FIFO:(First in first out),先进先出算法,如果缓存中的容量已经满了,那么会将最先进入缓存中的数据清除掉;
Scheduled:指定时间间隔清空算法,该算法会以指定的某一个时间间隔将Cache缓存中的数据清空;