mybatis底层为什么设计二层缓存?

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!

MyBatis 设计二级缓存(Second Level Cache)主要是为了解决 跨会话(SqlSession)的数据共享 和 高频重复查询的性能问题,其核心目标是减少数据库访问压力、提升系统性能。


1. 一级缓存的局限性

MyBatis 默认提供一级缓存(SqlSession 级别),在同一个 SqlSession 中多次执行相同的查询时,会直接从缓存中获取数据,避免重复查询数据库。然而:

  • 作用域限制:一级缓存仅在单个 SqlSession 内有效,不同 SqlSession 之间无法共享缓存。
  • 数据一致性风险:如果一个 SqlSession 更新了数据,其他 SqlSession 无法感知到数据变化,可能导致脏读。

二级缓存的作用 :

通过提供全局性、跨 SqlSession 的缓存,使得多个会话可以共享缓存数据,减少对数据库的重复访问。


2. 二级缓存解决的问题

(1) 减少数据库访问压力

  • 场景:在高并发场景下,多个用户可能频繁查询相同的数据(如商品信息、配置信息)。
  • 效果:通过二级缓存将热点数据存储在应用进程或分布式缓存中,减少对数据库的直接访问,显著降低数据库负载。

(2) 跨会话数据共享

  • 场景:用户 A 在 SqlSession1 中查询了数据,用户 B 在 SqlSession2 中也需要同样的数据。
  • 效果:二级缓存允许不同 SqlSession 共享同一份缓存数据,避免重复查询。

(3) 提升响应速度

  • 场景:复杂查询或关联查询(如多表 JOIN)的结果可以缓存,后续直接使用。
  • 效果:直接从内存中获取结果,比执行 SQL 解析、数据库 I/O 操作更快。

3. 二级缓存的设计特点

  1. 作用域 :

    二级缓存是 Mapper 级别 的,即同一个 Mapper 的多个 SqlSession 共享缓存。

    • 配置方式:在 Mapper XML 文件中通过 <cache> 标签启用。
  2. 存储机制:

    • 默认使用内存(基于 PerpetualCache),但可通过集成第三方缓存库(如 EhCache、Redis)扩展为分布式缓存。
    • 缓存的数据是序列化后的副本,读取时会反序列化,因此对象需要实现 Serializable 接口。
  3. 缓存策略:

    • LRU(Least Recently Used):淘汰最近最少使用的缓存。
    • FIFO(First In First Out):按缓存插入顺序淘汰。
    • SOFT/WEAK:基于 JVM 垃圾回收机制的缓存淘汰策略。
  4. 数据一致性保证:

    • 当执行 INSERT/UPDATE/DELETE 操作时,MyBatis 会刷新对应 Mapper 的二级缓存,避免脏读。

4. 适用场景与注意事项

适用场景:

  • 读多写少的业务(如商品详情页、新闻资讯)。
  • 对数据实时性要求不高的场景。

注意事项:

  • 数据一致性:二级缓存可能导致短暂的数据不一致(如分布式环境下),需结合业务容忍度权衡。
  • 序列化开销:缓存对象序列化/反序列化可能带来性能损耗。
  • 缓存失效:频繁更新的数据不适合二级缓存,会导致缓存频繁失效。

5. 对比一级缓存

特性 一级缓存 二级缓存
作用域 SqlSession 内部 Mapper 级别,跨 SqlSession
生命周期 随 SqlSession 关闭而销毁 持久化,直到显式刷新或配置过期
数据共享 不支持 支持
性能优化目标 会话内重复查询 跨会话高频查询

总结

MyBatis 的二级缓存通过跨会话共享数据,解决了高频重复查询的数据库压力问题,提升了系统性能。但其设计需要权衡数据一致性和缓存效率,在适合的业务场景(如读多写少)中合理配置,才能发挥最大价值。对于高一致性要求的场景,可能需要结合其他方案(如分布式缓存中间件或手动控制缓存刷新)。

相关推荐
m0_587383003 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
·云扬·3 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
怕浪猫3 小时前
2028编程圈很火的10个Skills
算法·面试·github
代码不停4 小时前
自动化测试(java)
java·开发语言·selenium·自动化
行百里er4 小时前
Redis 完结篇——Redis 热点问题在 Spring Boot 项目中实战
redis·后端
高频因子挖掘机5 小时前
只取最近 60 个交易日,却每次拉全历史:量化脚本变慢的原因与改法
后端·github·api
鬼手点金6 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
孟健6 小时前
从5000亿Token到83%字节匹配:AI逆向工程与重构的工程闭环实践
后端·架构·ai编程
paopaokaka_luck7 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
码事漫谈7 小时前
丢得静悄悄,谈一谈 Agent 的记忆是怎么没的
后端