MyBatis一级缓存生命周期完全绑定SqlSession,随其创建而初始化、关闭或清空而销毁;失效场景包括执行增删改操作、调用clearCache()、事务提交/回滚或SqlSession关闭。

MyBatis 一级缓存的生命周期**完全绑定在 SqlSession 实例上**,它不是独立存在的对象,而是 SqlSession 内部的一个状态(默认是 PerpetualCache 实例),随 SqlSession 的创建而初始化,随 SqlSession 的关闭或清空而失效或销毁。
一级缓存何时被清空
以下操作会清空当前 SqlSession 中的一级缓存(即让缓存失效,后续查询将重新查库):
-
执行任意更新操作(INSERT / UPDATE / DELETE):只要调用了
sqlSession.insert()、update()或delete(),缓存自动清空——这是 MyBatis 的默认行为,防止读到脏数据; -
显式调用
sqlSession.clearCache():手动清空缓存,适用于业务明确需要刷新本地视图的场景; -
SqlSession 关闭(
sqlSession.close())或提交/回滚后被回收:缓存对象随之被 GC 回收,生命周期自然结束。
一级缓存不会跨 SqlSession 共享
每个 SqlSession 拥有自己独立的一级缓存。即使两个 SqlSession 使用相同的 Mapper 接口、相同的 SQL 和参数,它们的缓存也互不影响:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- Session A 查询一次 user(id=1),结果存入 A 的缓存;
- Session B 同样查询 user(id=1),仍会发起新数据库查询,不会读取 A 的缓存;
- 这是设计使然——一级缓存本质是“会话级本地缓存”,不提供线程安全或跨会话一致性保证。
注意:OpenSession 重用与缓存延续性
如果一个 SqlSession 被重复使用(例如在 Spring 中未配置 SqlSessionTemplate 的 auto-commit 或作用域为 prototype),它的缓存会持续存在,直到被清空或关闭:
立即学习“Java免费学习笔记(深入)”;
- 多次
select相同语句 → 第二次起直接命中缓存; - 中间穿插了
update→ 缓存被清空,后续select重新查库; - 若长期持有 SqlSession(如单例模式错误复用),可能导致内存泄漏或数据陈旧——务必确保 SqlSession 是短生命周期、方法级或事务级的。
如何验证一级缓存是否生效
开启 MyBatis 日志(如 log4j 输出 DEBUG 级别),观察日志中是否出现重复 SQL 执行:
- 第一次查询:显示
Preparing: SELECT ...和数据库返回结果; - 第二次相同查询(未更新、未清空、同一 SqlSession):无 SQL 准备日志,仅输出结果映射过程,说明命中一级缓存。

















