MyBatis的缓存
MyBatis的一级缓存
- 一级缓存是
SqlSession
级别的,通过一个SqlSession
查询的数据会被缓存- 下一次查询相同的数据,就会从缓存中直接获取,不会从数据库中重新访问
- 一级缓存失效的四种情况:
- 使用了不同的SqlSession
- 同一个
SqlSession
,但是查询条件不同 - 同一个
SqlSession
,但是两次查询期间执行了一次增删改查的操作 - 同一个
SqlSession
,两次查询期间手动清空了缓存
MyBatis的二级缓存
- 二级缓存是
SqlSessionFactory
级别的,通过同一个SqlSessionFactory
创建的SqlSession
查询结果会被缓存- 此后如果执行相同的查询语句,结果就会从缓存中获取
- 开启条件:
- 在核心配置文件中,设置全局配置属性
cacheEnabed="true"
- 默认即为
true
- 默认即为
- 在映射文件中设置标签
<cache/>
(直接设置即可) - 二级缓存必须在
SqlSession
关闭或提交之后有效 - 查询的数据所转换的实体类型必须实现序列化接口
- 在核心配置文件中,设置全局配置属性
- 二级缓存失效的情况:
- 两次查询之间执行了任意的增删改
[!提示] 缓存只作用于
cache
标签所在的映射文件中的语句,如果混合使用注解与xml映射文件,在共用接口中的语句将不会被默认缓存 需要使用@CacheNamespaceRef
注解指定缓存作用域
- 两次查询之间执行了任意的增删改
[!直接使用cache的效果] - 映射语句文件中的所有 select 语句的结果将会被缓存。 - 映射语句文件中的所有 insert、update 和 delete 语句(增删改)会刷新缓存。 - 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。 - 缓存不会定时进行刷新(也就是说,没有刷新间隔)。 - 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。 - 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
二级缓存的相关配置
cache
标签的属性:eviction
:缓存回收策略,默认为LRU
LRU
:(Least Recently Used)最近最少使用的,移除最长时间不被使用的对象FIFO
:(First In First Out)先进先出,按对象进入缓存的顺序来移除他们SOFT
:软引用,基于垃圾回收器状态和软引用规则移除对象WEAK
:弱引用,更积极地基于垃圾收集器状态和弱引用规则移除对象
flushInterval
:刷新间隔,单位为毫秒- 默认情况下不进行设置,也就是无刷新间隔
size
:引用数目- 代表缓存最多可以存储多少个对象,太大可能导致内存溢出
readOnly
:只读true
:只读缓存,会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,可以提高性能false
:读写缓存,会返回缓存对象的拷贝(通过序列化的方式),速度缓慢,但是相对安全
MyBatis缓存查询的顺序
- 先查询二级缓存
- 二级缓存中可能存在其他程序已经查出来的数据,可以直接使用
- 再查询一级缓存
- 最后查询数据库
- 关闭
SqlSession
后,一级缓存中的数据会写入二级缓存