MyBatis 的一级、二级缓存

MyBatis 提供了强大的缓存机制,以提高数据库查询性能。缓存主要分为 一级缓存二级缓存,它们分别应用于不同的范围和场景。

1️⃣ 一级缓存(Local Cache)

📌 定义

  • 作用范围:SqlSession 级别
  • 存储位置:SqlSession 内存中
  • 默认开启
  • 失效条件:
    • SqlSession 关闭
    • 执行 insertupdatedelete 操作
    • 执行 select 时手动刷新缓存 sqlSession.clearCache()
    • 查询不同的 SQL 语句

🚀 示例代码

SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.getUserById(1); // 第一次查询,数据从数据库加载
User user2 = mapper1.getUserById(1); // 第二次查询,数据从缓存获取
sqlSession1.close();

2️⃣ 二级缓存(Global Cache)

📌 定义

  • 作用范围:Mapper(Namespace)级别,多 SqlSession 共享
  • 存储位置:MyBatis 全局级别缓存,通常存储在 PerpetualCache
  • 默认关闭,需要手动开启
  • 失效条件
    • 执行 insertupdatedelete 操作后,缓存会自动清除
    • 直接操作数据库

🚀 使用方式

  1. 开启二级缓存(在 mybatis-config.xmlmapper.xml 中设置):
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
  1. 在 Mapper 配置中启用缓存
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
  • eviction="LRU":最近最少使用的缓存清理策略
  • flushInterval="60000":60 秒自动刷新缓存
  • size="512":最大缓存 512 个对象
  • readOnly="true":只读,提高并发效率
  1. 示例代码
SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.getUserById(1);
sqlSession1.close(); // 数据写入二级缓存

SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.getUserById(1); // 从二级缓存读取数据
sqlSession2.close();

3️⃣ 一级缓存 vs. 二级缓存 📊

对比项一级缓存二级缓存
作用范围SqlSessionMapper(Namespace)级别,多 SqlSession 共享
默认开启✅ 是❌ 否(需手动开启)
失效条件SqlSession 关闭、增删改操作增删改操作、数据库更新、缓存超时
适用场景单个会话内查询优化适用于多个 SqlSession 共享数据

4️⃣ 数据共享问题

二级缓存的主要作用之一是跨 SqlSession 共享数据,但也会引发一些问题:

🔸 数据一致性问题

  • 由于二级缓存存储在 Mapper 级别,数据修改后不会立即更新缓存,可能导致数据不一致。
  • 解决方案:
    • 使用事务控制,确保数据库更新后及时刷新缓存。
    • 定期刷新缓存,通过 flushInterval 机制自动更新。
    • 禁用二级缓存,对于高实时性数据建议不使用。

🔸 并发访问问题

  • 默认情况下,MyBatis 二级缓存是 readOnly,多个线程访问时不会有并发问题。
  • 如果设置 readOnly="false",则需要考虑线程安全问题。

🔸 分布式环境中的缓存共享

  • 单机应用:二级缓存可以有效减少数据库访问,提高性能。
  • 分布式应用:多个服务实例可能无法共享 MyBatis 二级缓存,导致缓存失效或不一致。
  • 解决方案:
    • 采用 Redis、EhCache 等第三方分布式缓存代替 MyBatis 内置缓存。
    • 结合 消息队列(MQ) 机制,在数据更新时广播清除缓存。

5️⃣ 总结 🚀

一级缓存 适用于 单个 SqlSession,默认开启,生命周期短。

二级缓存 适用于 多个 SqlSession 共享,默认关闭,需要手动开启。

数据一致性问题 是二级缓存的关键挑战,需谨慎使用。

分布式架构下建议使用第三方缓存(如 Redis)以实现缓存共享。

✅ 适用于 读多写少 的场景,如查询热门数据、字典数据等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值