mybatis 缓存
一级缓存
在全局配置文件中的 setting 节点中配置 localCacheScope 为 SESSION,表示一级缓存作用域是 SESSION
<setting name="localCacheScope" value="SESSION"/>
一级缓存不能关闭,但是可以更改作用范围,也就是说 value 不能为空,可选的值有 SESSION
和 STATEMENT
。
SESSION
表示当前会话的所有查询都会被缓存;STATEMENT
表示对当前执行的 sql 生效,sql 执行结束就清空缓存。
描述太官方,简言之就是 SESSION
打开一级缓存,STATEMENT
不适用一级缓存
场景1
同一个 SqlSession 查询一样的 MappedStatement,利用缓存
SqlSession1 | SqlSession1 |
---|---|
queryById(1) | |
缓存中没有,查询数据库并加入缓存,返回 | |
queryById(1) | |
缓存命中,直接返回 |
场景2
不同 SqlSession,查询和更新导致 脏数据
SqlSession1 | SqlSession2 | SqlSession1 |
---|---|---|
queryById(1) | ||
缓存中没有,查询数据库并加入缓存,返回 | ||
updateById(1) | ||
清空 SqlSession2 的缓存 | ||
queryById(1) | ||
缓存命中,直接返回 |
源码就不分析了,大致描述下就行了
- Mybatis 打开一个会话会创建一个 SqlSession
- 每次创建 SqlSession 里面都会创建一个新的 Executor,Executor 持有一个 PerpetualCache 对象,这个里面就是缓存结果
- 当会话结束,也就是调用 SqlSession.close() 时会释放 PerpetualCache
- 当会话执行更新操作,也就是调用 SqlSession 的 insert、update、delete 方法会释放 PerpetualCache
- 当 SqlSession 调用 clearCache() 时也会释放 PerpetualCache
总结一下:
- 一级缓存基于 SqlSession,不能关闭,能更改作用域
- 一级缓存的 SESSION 作用域可能产生脏数据,使用 STATEMENT 解决
二级缓存
开启二级缓存
-
全局配置文件启用二级缓存
<settings> <!-- 开启二级缓存 --> <setting name="cacheEnabled" value="true"/> </settings>
-
映射文件配置二级缓存
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mj.center.credit.dao.mapper.CreditBusinessBillMapper"> <!-- 当前 mapper 开启二级缓存 --> <cache /> <!-- 当前语句加入缓存 --> <select useCache="true" id="queryById" resultType="com.mj.center.credit.dao.eo.UserEo"> select * from t_user where id = #{id} </select> <!-- 当前语句执行后清空当前 mapper 的二级缓存 --> <select flushCache="true" id="queryByCode" resultType="com.mj.center.credit.dao.eo.UserEo"> select * from t_user where code = #{code} </select> </mapper>
-
返回对象实现序列化接口
cache 配置项
<cache />
映射文件中简单这样写就行了,没有配置项表示都是用默认的配置,可以手动配置,全部的配置:<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
- eviction:淘汰策略
- LRU – 最近最少使用的:移除最长时间不被使用的对象(默认)
- FIFO – 先进先出:按对象进入缓存的顺序来移除它们
- SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
- WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
- flushInterval:过期时间,单位毫秒,默认不过期
- size:缓存大小,表示能存放多少个缓存对象
- readOnly:只读模式,默认 true
- cachetype:缓存实现类,自定义缓存时配置
select 配置项
- useCache:当前 select 使用缓存
- flushCache:当前语句执行完就清空缓存
注意事项
- 只在单表使用,联表查询不要使用(原因还是会缓存污染,比如 Amapper 联合查询了 a 表和 b 表进行缓存,Bmapper 更新了 b 表数据)
- 当为 select 下:flushCache 默认为 false,useCache 默认为 true
- 当为 insert、update、delete 下:flushCache 默认为 true,没有 useCache 属性
自定义缓存
需要在映射文件中的 cache 标签指定 cacheType,值是实现了org.apache.ibatis.cache.Cache
的一个类。
用的太少了,当下不整理了,其实现在一二级缓存基本都不会配置,如果需要缓存都是直接考虑 redis 了