一级缓存是sqlsession级本地缓存,各会话间完全隔离、互不共享;其生命周期与sqlsession绑定,关闭即销毁,设计初衷是避免数据污染、保障事务边界清晰、降低实现复杂度。

因为一级缓存是 SqlSession 实例级别的本地缓存,它直接绑定在单个 SqlSession 对象的内存中,不同 SqlSession 是彼此完全隔离的对象,各自维护独立的缓存 Map(通常是 PerpetualCache),自然无法共享数据。
一级缓存的存储位置和生命周期
每个 SqlSession 在创建时都会初始化一个专属的本地缓存结构(如 localCache 字段),这个缓存仅存在于该对象的堆内存里。一旦 SqlSession 关闭或被回收,缓存也随之销毁。两个 SqlSession 即使执行完全相同的 SQL 和参数,它们的缓存 key 也互不感知、互不影响。
批量分析录音转写,输出多维度拓客报告。触发词:录音分析、总结、音频总结、拜访记录总结。当用户提及「分析录音」「看看录音数据」「最近的录音」「通话记录」且意图为批量统计/分析时触发。仅出现「录音」或「拜访」时需结合上下文,若仅查看单条详情则不触发。
设计初衷就是隔离而非共享
- 避免跨会话的数据污染:一个会话里的临时修改(比如未提交的 update)不该影响其他会话的读取结果
- 保障事务边界清晰:每个 SqlSession 通常对应一次数据库会话或一个业务事务,缓存只服务于当前上下文
- 降低实现复杂度:无需处理分布式锁、缓存同步、失效广播等难题
常见误解与验证方式
有人误以为“查的是同一张表、同一个 ID 就该命中缓存”,但实际缓存 key 的构成包括:MappedStatement ID + 参数值 + 分页信息 + 环境配置,而这些都绑定在当前 SqlSession 所属的执行环境中。你可以通过开启 MyBatis DEBUG 日志(logging.level.org.apache.ibatis=DEBUG)观察:不同 SqlSession 的相同查询,每次都会打印 Preparing: SELECT...,说明根本没走缓存。
想跨会话共享?得用二级缓存或外部缓存
如果确实需要多个 SqlSession 共享查询结果,应启用 MyBatis 二级缓存(作用域为 Mapper namespace),或更推荐接入 Redis、Caffeine 等独立缓存中间件——它们不受 SqlSession 生命周期限制,支持主动刷新、过期控制和集群同步。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










