温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java mybatis为何缓存不生效

发布时间:2026-09-02 18:43:18 来源:亿速云 阅读:96 作者:小樊 栏目:编程语言

MyBatis 缓存不生效是开发中经常遇到的问题,通常分为**一级缓存(SqlSession 级别)二级缓存(Mapper / namespace 级别)**两种情况。下面从常见原因 + 排查思路给你系统说明。


一、MyBatis 一级缓存不生效(最常见)

1️⃣ 使用了不同的 SqlSession

一级缓存只在同一个 SqlSession 内有效

SqlSession s1 = sqlSessionFactory.openSession();
s1.selectOne("getUser", 1);

SqlSession s2 = sqlSessionFactory.openSession();
s2.selectOne("getUser", 1); // 不会走缓存

✅ 解决:

  • 同一个请求中复用同一个 SqlSession
  • Spring 中通常一个事务 = 一个 SqlSession

2️⃣ 方法中执行了写操作(insert / update / delete)

一级缓存会在以下情况被清空:

  • update
  • delete
  • insert
userMapper.selectById(1);
userMapper.update(user);
userMapper.selectById(1); // 不会走一级缓存

3️⃣ 手动调用了 clearCache()

sqlSession.clearCache();

4️⃣ 查询条件不同(SQL + 参数必须完全一致)

selectById(1);
selectById(2); // 不是同一条缓存

二、MyBatis 二级缓存不生效(更容易踩坑)

1️⃣ 没有开启二级缓存

MyBatis 默认 二级缓存是关闭的(3.4+ 后默认开启但需配置)

✅ 需要:

<settings>
  <setting name="cacheEnabled" value="true"/>
</settings>

2️⃣ Mapper 没加 <cache/>

<mapper namespace="com.xxx.UserMapper">
  <cache/>
</mapper>

或注解方式:

@CacheNamespace
public interface UserMapper {}

3️⃣ 实体类没有序列化

二级缓存可能跨 SqlSession,对象必须可序列化

public class User implements Serializable

否则:

  • 缓存直接失效
  • 或抛 NotSerializableException

4️⃣ 使用了不同的 Mapper namespace

二级缓存是 namespace 级别

UserMapper.selectById(1);
OrderMapper.selectUser(1); // 不会共享缓存

5️⃣ Spring + MyBatis 事务问题

二级缓存只在 SqlSession 提交后才生效

@Transactional
public void test() {
    userMapper.selectById(1);
    userMapper.selectById(1); // 可能不命中
}

✅ 解决:

  • 方法结束(事务提交)
  • 或不在事务内查询

6️⃣ 使用了分页 / 不同 SQL

select * from user
select * from user limit 10

→ 视为不同缓存 key


7️⃣ 使用了 PageHelper 等插件

PageHelper 会修改 SQL,可能导致缓存 key 变化。


三、Spring + MyBatis 常见“看起来没缓存”的原因

✅ SqlSession 每次都新建

  • 没使用事务
  • 每次 mapper 调用都新开 SqlSession

解决:

@Transactional
public User test() {
    userMapper.selectById(1);
    return userMapper.selectById(1);
}

四、快速排查清单 ✅

  • [ ] 是否同一个 SqlSession?
  • [ ] 是否执行了增删改?
  • [ ] 是否开启 cacheEnabled?
  • [ ] Mapper 是否配置 <cache/>
  • [ ] 实体是否 Serializable?
  • [ ] 是否在事务中?
  • [ ] SQL 和参数是否完全一致?

五、结论(重点)

MyBatis 缓存不生效,90% 是因为:

  • 不同 SqlSession
  • 中间有写操作
  • 二级缓存没配置 / 没序列化
  • Spring 事务导致缓存未提交

如果你愿意,可以把:

  • MyBatis 版本
  • 是否用 Spring / Spring Boot
  • Mapper 配置
  • 测试代码

贴出来,我可以直接帮你定位是哪一条导致的

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI