- 一级缓存
- 默认启用,并且不能控制。有时会产生难以发现的错误。
- 通过select标签的flushCache属性来控制。
- 生命周期是SqlSession,在同一个SqlSession中查询时,MyBatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。
- 任何的insert、update和delete操作都会清空一级缓存。
- 二级缓存
- 生命周期是SqlSessionFactory。
- 通过全局配置中的cacheEnabled参数来控制。
- 与命名空间相绑定,即二级缓存需要配置在Mapper.xml文件中,或者配置在Mapper.java接口中。在映射文件中,命名空间就是XML根节点mapper的namespace属性。在Mapper接口中,命名空间就是接口的全限定名称。
- 映射语句文件中的所有select语句将会被缓存。
- 映射语句文件中的所有insert、update和delete语句会刷新缓存。
- 缓存会使用指定的算法来收回,通过cache标签的eviction属性来设置,默认是LRU(最近最少使用的)。
- 缓存会使用指定的时间间隔来刷新,通过flushInterval属性来设置,单位是毫秒,默认不会刷新。
- 缓存会存储查询结果的1024个引用,通过size属性来设置。
- 缓存可以是可读可写的(线程安全的,通过序列化实现),或者是只读的(性能优势 ,返回同一个对象),默认可读可写。
- 当只使用注解方式配置二级缓存时,通过@CacheNamespace实现。
- 如果同时配置,需要使用参照缓存,二选一。
@CacheNamespaceRef(RoleMapper.class)
<cache-ref namespace = “tk.mybatis.simple.mapper.RoleMapper”/>
- 当调用close方法关闭SqlSession时,SqlSession才会保存查询数据到二级缓存中。
- 默认提供的缓存实现是基于Map实现的内存缓存,也可以通过集成缓存框架(EhCache)或者缓存数据库(Redis)来实现。
- 当某几个表可以作为一个业务整体时,通常是让几个会关联的表同时使用同一个二级缓存,避免脏读。
- 适用场景
(1)以查询为主的应用
(2)绝大多数以单表存在操作时
(3)可以按业务划分对表进行分组时
(4)脏读对系统没有影响时