MyBatis 缓存不生效是开发中经常遇到的问题,通常分为**一级缓存(SqlSession 级别)和二级缓存(Mapper / namespace 级别)**两种情况。下面从常见原因 + 排查思路给你系统说明。
一级缓存只在同一个 SqlSession 内有效
SqlSession s1 = sqlSessionFactory.openSession();
s1.selectOne("getUser", 1);
SqlSession s2 = sqlSessionFactory.openSession();
s2.selectOne("getUser", 1); // 不会走缓存
✅ 解决:
一级缓存会在以下情况被清空:
userMapper.selectById(1);
userMapper.update(user);
userMapper.selectById(1); // 不会走一级缓存
sqlSession.clearCache();
selectById(1);
selectById(2); // 不是同一条缓存
MyBatis 默认 二级缓存是关闭的(3.4+ 后默认开启但需配置)
✅ 需要:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<cache/><mapper namespace="com.xxx.UserMapper">
<cache/>
</mapper>
或注解方式:
@CacheNamespace
public interface UserMapper {}
二级缓存可能跨 SqlSession,对象必须可序列化
public class User implements Serializable
否则:
二级缓存是 namespace 级别的
UserMapper.selectById(1);
OrderMapper.selectUser(1); // 不会共享缓存
二级缓存只在 SqlSession 提交后才生效
@Transactional
public void test() {
userMapper.selectById(1);
userMapper.selectById(1); // 可能不命中
}
✅ 解决:
select * from user
select * from user limit 10
→ 视为不同缓存 key
PageHelper 会修改 SQL,可能导致缓存 key 变化。
解决:
@Transactional
public User test() {
userMapper.selectById(1);
return userMapper.selectById(1);
}
<cache/>?MyBatis 缓存不生效,90% 是因为:
- 不同 SqlSession
- 中间有写操作
- 二级缓存没配置 / 没序列化
- Spring 事务导致缓存未提交
如果你愿意,可以把:
贴出来,我可以直接帮你定位是哪一条导致的。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。