一级缓存:默认开启
- MyBatis一级缓存的生命周期和SqlSession一致。
- MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
- MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,
- 脏数据原因:在一个sqlSession中执行几个查询操作,但在这些查询操作中间另一个sqlSession去更新了数据库,而这次的更新第一个sqlSession是无感知的,此时它再去查询依然是在缓存中查询
- 使用mybatis-spring时一级缓存失效(原因没弄懂)
二级缓存:默认关闭
生命周期为namespace
开启二级缓存的步骤:一开启全局缓存(setting中 默认开启)
二在对应的mapper.xml中开启
当sqlSession没有关闭时或者提交时,这次查询的数据不会缓存到二级缓存
- MyBatis的二级缓存相对于一级缓存来说,实现了
SqlSession
之间缓存数据的共享,同时粒度更加的细,能够到namespace
级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。 - MyBatis在多表查询时,极大可能会出现脏数据(一个namespace中的缓存变化对另一个namespace是无感知的),有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
- 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高
总结:
- 映射语句文件中的所有 insert、update 和 delete 语句会清空缓存(一级和二级)。
- 更深入:https://tech.meituan.com/2018/01/19/mybatis-cache.html