缓存
缓存
功能
提高查询效率,减少数据库压力。当缓存中有结果时将不再查询数据库。
用途
用于查询,适合查询较多的场合。
注意
insert、update、delete都会使缓存失效。或超时失效
一级缓存
作用
缓存是一个map。
SqlSession会将statementId,params,rowBounds作为key,结果为value。
执行查询时会先判断cache总是否有本次的key。存在且未超时,直接返回value;若不存在,则将本次key和value存入cache,并返回value
作用域
SqlSession(实际由Executor存储并管理),不能跨Session共享
生命周期
创建SqlSession对象时,会创建缓存Executor
调用clearCache或增删改时,会清空缓存SqlSession关闭时,缓存Executor也关闭
失效
调用clearCache清空一级缓存
脏数据
多个session之间缓存可能不同,形成脏数据
可以设置一级缓存为statement级别,每次查询都将清除一级缓存
设置
MyBatis默认开启一级缓存,且无法关闭
使用
默认已经使用
二级缓存
作用
跨session共享缓存
查询语句执行流程为:二级缓存 ⇋ 一级缓存 ⇋ 数据库
作用域
namespace(实际由CachingExecutor装饰器维护,根据配置选用不同的Executor执行)
设置
全局总开关
settings中有cacheEnable属性,用于配置全局缓存是否开启,默认值为true
1 | <setting name="cacheEnabled" value="true"/> |
全局配置
MyBatis默认没有开启二级缓存,需要在mapper配置文件中添加cache配置或使用@CacheNamespace注解
https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache
配置该mapper缓存策略为FIFO,刷新时间为60秒,缓存元素为512个,只读
1 | <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> |
脏数据
当多表连接时MapperAB,缓存会保存在MapperAB,但通过MapperB更新单表的数据只会清空B的缓存,对MapperAB没有影响,这时,MapperAB将读取脏数据
解决方法
在MapperB内通过<cache-ref namespace="MapperA"/>使两个Mapper使用同一缓存(或使用@CacheNamespaceRef注解)
使用
查询后必须commit才会将结果加入二级缓存
session1查询后未提交,则二级缓存没有保存该结果,session2将查询数据库
缺点
- 二级缓存没有一级缓存效率高
- 多表操作时,二级缓存会产生脏数据