MyBatis二级缓存需在Mapper XML中配置<cache/>标签,POJO实现Serializable接口,全局cacheEnabled设为true,且仅对select生效,增删改操作默认清空该namespace缓存。

MyBatis 的二级缓存是 Mapper 级别的缓存,它在同一个命名空间(即同一个 Mapper 接口对应的 XML 文件)下跨 SqlSession 共享。要启用它,核心是在 Mapper XML 文件中添加 <cache> 标签,并确保相关条件满足。
1. 在 Mapper XML 中声明 <cache> 标签
在对应的 *Mapper.xml 文件的 <mapper> 标签下直接添加 <cache/>,这是最简启用方式:
<mapper namespace="com.example.UserMapper">
<cache/>
<select id="selectById" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>该配置使用 MyBatis 默认的缓存实现(PerpetualCache),底层基于 HashMap,且默认开启 读写缓存、阻塞式清空、未设置刷新间隔和大小限制。
2. 确保 POJO 实现 Serializable 接口
二级缓存会序列化对象存储,所以被缓存的实体类必须实现 java.io.Serializable,否则运行时抛出异常:
立即学习“Java免费学习笔记(深入)”;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
// getter/setter...
}不实现 Serializable 是二级缓存最常见的失败原因。
3. 开启全局二级缓存开关(MyBatis 3.4.0+ 默认已开)
检查 mybatis-config.xml 中是否禁用了缓存:
<settings> <setting name="cacheEnabled" value="true"/> <!-- 默认就是 true,一般无需显式配置 --> </settings>
如果该值为 false,则所有 <cache> 都会被忽略。
4. 注意缓存生效的前提和边界
二级缓存只对 <select> 查询生效;执行了 <insert>、<update> 或 <delete> 后,该 Mapper 下的整个缓存会被清空(除非手动配置 flushCache="false"):
- 同一个
namespace下的查询共享缓存,不同 Mapper 互不影响 - 缓存键由
MappedStatement ID + 参数构成,参数需可序列化 - 若 SQL 中包含动态语句(如
<if>),只要最终生成的 SQL 和参数一致,仍命中缓存 - 事务提交后才将数据写入二级缓存,未提交的修改对其他 Session 不可见
不复杂但容易忽略:加了 <cache> 只是第一步,POJO 序列化、SQL 执行逻辑、事务边界共同决定缓存是否真正复用。


















