MyBatis缓存机制
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。
MyBatis一级缓存
- 默认情况下,MyBatis 是启用一级缓存/本地缓存/local Cache,它属于 SqlSession 级别。
- 同一个 SqlSession 的接口对象调用了相同的 select 语句,会直接从缓存中直接获取,而不需要再去查询数据库。即第一次执行select语句时,会获得数据库的连接,并从数据库中获取结果集,再把结果集存放值一级缓存中,第二次执行相同的select语句时,会先从一级缓存(localCache)中获取数据。
- 一级缓存失效分析:
- 关闭 SqlSession 会话后,再次获取会话并进行查询,会到数据库中进行查询。
- 当调用 SqlSession 对象的 clearCache() 方法,清空缓存,也会使一级缓存失效。
- 对一级缓存中的对象信息进行了修改,就会使该一级缓存失效。即对缓存中存储的数据执行了DML语句。
MyBatis二级缓存
- 与一级缓存的区别:
- 一级缓存的作用域是 SqlSession 级别,只对一次会话生效。
- 二级缓存的作用域是全局范围,针对不同的会话都会生效。
- 二级缓存的配置方式:在 MyBatis 核心全局配置文件的 setttings 中加入设置 cacheEnabled,设置为 true(默认)。
<!--mybatis-config.xml-->
<settings>
<!--配置全局性地开启或关闭所有映射器配置文件中已配置的任何缓存设置,默认为true-->
<setting name="cacheEnabled" value="true"/>
</settings>
- 对于二级缓存的使用,需要的具体的XxxMapper.xml中配置二级缓存机制。
<!--
XxxMapper.xml
cache 表示启用二级缓存
eviction 表示缓存的清除策略,默认的清除策略是 LRU。
清除策略分为:
1. LRU – 最近最少使用:移除最长时间不被使用的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3. SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
4. WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
flushInterval 表示缓存的刷新间隔,单位为毫秒
size 表示引用数目(缓存对象的大小),默认值是 1024
readOnly
表示设置为只读,只读的缓存会给所有调用者返回缓存对象的相同实例,可以提升性能,
如果需要进行修改操作,则可以将只读设置为false,默认为false
-->
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
- 第一次查询:从数据库中获取
- 第二次查询:从缓存中获取(新的sql会话),从输出日志中可以看出,并未获得连接和向数据库发送sql语句。
- 二级缓存的使用细节:
- 在 MyBatis 核心配置文件中可以全局性的开启和关闭任何一配置的二级缓存。
- 二级缓存针对于不同的会话都生效。
- 在具体的 XxxMapper.xml 配置文件的 select 标签中,存在 useCache 属性,可以指定是否使用配置的缓存,默认为true(即使用)。
- 在具体的 XxxMapper.xml 配置文件的 update,delete,insert 标签中,存在 flushCache 属性,可以指定是否将执行 DML 语句后刷新缓存,默认为 true。
- 缓存细节说明:
- 不会出现一级缓存和二级缓存中存在相同数据的情况,因为二级缓存中的数据是在一级缓存关闭之后才有的,即关闭一个 SqlSession 后,才会把一级缓存的数据存放入二级缓存。
- 对于二级缓存,有很多性能高效的第三方缓存库,例如:EHcache、OSCache…