MyBatis 缓存详解
https://www.cnblogs.com/wuzhenzhao/p/11103043.html MyBatis 缓存详解
https://blog.csdn.net/GDUT_Trim/article/details/120117911 MyBatis(一):BaseExecutor与CachingExecutor
https://blog.csdn.net/ThinkWon/article/details/101293216 MyBatis核心类
一级缓存(本地缓存)
- Mybatis的一级缓存存放在SqlSession(会话)的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。如果同一个SqlSession中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当Map缓存对象中已经存在改键值时,则会返回缓存中的对象。(一个SqlSession连续两次查询 得到的是同一个java对象)
- 任何的insert update delete操作都会清空一级缓存(增删改任何记录都会清空当前SqlSession的缓存)。
-
Spring整合Mybatis的时候一级缓存的问题:(默认一级缓存是开启的)
在未开启事物的情况之下(@Transactional),每次查询,spring都会关闭旧的sqlSession而创建新的sqlSession,因此此时的一级缓存是没有启作用的
在开启事物的情况之下(@Transactional),spring使用threadLocal获取当前资源绑定同一个sqlSession,因此此时一级缓存是有效的
- 总结: 一级缓存就是mapper.aaa(c,d)。 同一mapper 同一方法 同一参数。 SqlSession连续两次查询 得到的是同一个java对象(通过反序列化得到)。
- 如何实现呢。
- 利用 ThreadLocal (当前线程变量副本)和 map 实现。 ThreadLocal<Map<Object, Object>> 把 请求方法+参数 通过指定算法生成key 放到map 中,并把map 放到ThreadLocal 中,当同 同一mapper 同一方法 同一参数 查询时,会去map中的数据。 然后把数据反序列化出来,就不用和数据库交付了。
-
https://blog.csdn.net/u013887008/article/details/80379938
-
二级缓存
- 二级缓存是用来解决一级缓存不能跨会话共享的问题的,范围是namespace 级别的,可以被多个SqlSession 共享,生命周期和应用同步(同一接口里面的同一方法 多线程共享数据)。如果你的MyBatis使用了二级缓存,并且你的Mapper和select语句也配置使用了二级缓存,那么在执行select查询的时候,MyBatis会先从二级缓存中取输入,其次才是一级缓存,即MyBatis查询数据的顺序是:二级缓存 —> 一级缓存 —> 数据库。
- 每个sqlSession都有自己的一级缓存,多个sqlSession共享二级缓存
- Mybatis二级缓存可以理解为存在SqlSessionFactory的生命周期
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构