MyBatis(8)一级缓存、二级缓存

MyBatis 的缓存分为一级缓存和二级缓存,这两种缓存机制主要用于减少数据库的查询次数,提高应用的执行效率。

一级缓存(Local Cache)

一级缓存是指 MyBatis 中的 SqlSession 级别的缓存。在操作数据库时,同一个 SqlSession 的多次查询,如果查询条件相同,会直接从缓存中获取数据,不会再次访问数据库。

原理
  • 一级缓存默认是开启的,其生命周期与 SqlSession 一致。
  • 一级缓存是通过一个 Map 实现的,Map 中的 key 是由 SQL 语句、参数等信息组成的,value 就是查询的结果对象。
代码演示

考虑以下 MyBatis 查询操作:

try (SqlSession session = sqlSessionFactory.openSession()) {
    BlogMapper mapper = session.getMapper(BlogMapper.class);
    Blog blog1 = mapper.selectBlog(101);
    Blog blog2 = mapper.selectBlog(101);  // 这次查询会直接从一级缓存中获取数据
}
缓存失效情况

一级缓存会在以下情况下失效:

  1. 不同的 SqlSession 对相同数据的查询不会共享缓存。
  2. 在同一个 SqlSession 中,如果对数据进行了增删改操作(这些操作可能会改变数据),一级缓存会被清空。
  3. 在同一个 SqlSession 中,如果调用了 clearCache() 方法,也会清空缓存。
  4. 如果两次查询之间手动提交了事务,那么缓存也会被清空。

二级缓存(Global Cache)

二级缓存是指 MyBatis 中的映射器(Mapper)级别的缓存。不同的 SqlSession 可以共享二级缓存,即二级缓存是跨 SqlSession 的。

启用二级缓存

要启用二级缓存,需要进行一些配置:

  1. 在 MyBatis 的配置文件中,设置全局配置属性 cacheEnabled=true(默认就是true)。
  2. 在映射器(Mapper)XML文件中添加 <cache/> 标签。
  3. 实体类需要实现序列化接口。
代码演示
<!-- 在Mapper XML中启用二级缓存 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
原理
  • MyBatis 的二级缓存是跨 SqlSession 的,它通过使用一个全局的 Map 来存储缓存数据。
  • 当一个 SqlSession 对象需要查询数据时,它会先在一级缓存中查找,如果没有找到,再去二级缓存中查找。如果二级缓存中也没有,才会执行数据库查询。
  • 数据更新操作会清空二级缓存,以保证数据的一致性。
缓存失效情况
  1. 映射器中的某个语句触发了更新(增删改),该映射器下所有的缓存都会被清空。
  2. SqlSession 调用了 commit() 提交事务,那么触发该 SqlSession 中所有 Mapper 的缓存清空。
  3. 缓存配置中的 flushInterval 时间到了,缓存也会被清空。

注意事项

  • 事务性:一级和二级缓存都不能解决跨数据库事务的缓存一致性问题,因此在使用缓存的时候需要注意数据的一致性问题。
  • 缓存穿透:在设计缓存的时候,还需考虑缓存穿透的问题,合理设置缓存查询的条件。
  • 性能考量:虽然缓存可以提高查询效率,减少数据库压力,但是不当的使用也会增加内存的压力,甚至可能因为缓存同步等问题反而降低系统性能,使用时需谨慎。

通过深入理解和合理使用 MyBatis 的一级缓存和二级缓存,可以有效地提高应用程序与数据库交互的效率。

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辞暮尔尔-烟火年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值