MyBatis缓存
1 一级缓存(本地缓存)
- 与数据库同一次会话期间查询到的数据会放在本地缓存中,以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
- 一级缓存是sqlSession级别的缓存,是一直开启的
1.1 一级缓存失效的四种情况
- sqlSession不同:一级缓存是sqlSession级别的缓存,所以如果重新开一个sqlSession,并不会共享其他sqlSession的缓存,仍然需要发送请求到数据库进行查询
- sqlSession相同,查询条件不同:这种情况很好理解,因为之前没有查询过,所以在一级缓存中没有对应的数据
- sqlSession相同,两次查询间执行了增删改操作:MyBatis执行增删改操作会清空缓存
- sqlSession相同,手动清空了一级缓存:调用SqlSession对象的clearCache方法清空一级缓存
2 二级缓存(全局缓存)
- 二级缓存是namespace级别的缓存
2.1 工作机制
- 一个session过程中查询的数据会被放在当前session的一级缓存中
- 如果session关闭,一级缓存中的数据就被保存到二级缓存中,从而新的session查询就可以参照二级缓存
- 不同namespace查出的数据会被放在自己对应的缓存中
2.2 使用
- 开启全局二级缓存配置,
1 | <setting name="cacheEnabled" value="true"/> |
- 在Mapper xml文件配置使用二级缓存,
1 | <mapper namespace="com.lnhoo.mapper.EmployeeMapper"> |
- 实现POJO的序列化接口
2.3 cache标签参数
参数 | 功能 |
---|---|
eviction | 缓存的回收策略, LRU:最近最少使用的,移除最长时间不被使用的对象 FIFO:先进先出,按对象进入缓存的顺序移除 SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象 WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则地对象 |
flushInterval | 缓存刷新间隔,即每隔多少毫秒清空缓存,默认不清空 |
readOnly | 是否只读, 只读:MyBatis认为所有访问缓存的操作都是只读操作,不会修改数据;为了加快获取速度,直接将数据在缓存中的引用返回给用户;不安全,但是速度快 读写,MyBatis认为获取的数据可能会被修改,会利用序列化、反序列化技术克隆一份新的数据;安全,但是速度慢 |
size | 缓存的元素个数 |
type | 自定义的缓存实现类(通过实现MyBatis Cache接口) |
2.4 和缓存有关的设置、属性
- 1)cacheEnabled:决定二级缓存是否启用
- 2)useCache:每个select标签都有一个“useCache”属性,决定是否缓存当前sql查询到的数据,默认为true;useCache决定的是二级缓存,对一级缓存无影响
- 3)flushCache:每个增删改标签都有一个“flushCache”属性,决定是否在sql执行后清空一级、二级缓存
- 4)sqlSession.clearCache():只清除当前session的一级缓存
- 5)localCacheScope:本地缓存作用域,默认值为“SESSION”,可选值为“STATEMENT”
3 MyBatis整合ehcache
3.1 导入适配器包
1 | <dependency> |
3.2 导入第三方缓存包
1 | <!-- https://mvnrepository.com/artifact/org.ehcache/ehcache --> |
3.2 Mapper xml配置使用自定义缓存
1 | <mapper namespace="com.lnhoo.mapper.EmployeeMapper"> |
- 可以通过cache标签的type属性指定自定义的缓存实现类
3.3 引用cache配置
- 有时候希望能够重用其他namespace的cache配置,可以使用cache-ref标签,
1 | <cache-ref namespace="com.lnhoo.mapper.EmployeeMapper"/> |