全面了解MyBatis缓存机制

缓存机制

在了解MyBatis的缓存机制之前,我们需要先了解一下缓存机制是什么,他的工作机制是什么,缓存策略有哪些。

先说一下缓存机制是什么:
缓存机制是一种用于提高系统性能和效率的技术,它通过在内存中存储数据的副本,减少对数据库或其他后端系统的直接访问次数,从而加快数据访问速度。缓存机制广泛应用于计算机系统、数据库、Web 应用程序等领域。

1. 缓存机制起源

    在计算机发展的早期阶段,处理器的速度与内存的速度相对接近,处理器可以直接从内存中读取指令和数据。然而,随着处理器技术的快速进步,特别是处理器时钟频率的提高,处理器执行指令的速度大幅提升,但内存访问速度的提升却相对缓慢。
    这一速度差距导致了一个严重的瓶颈问题:处理器往往需要等待较长时间才能从内存中获取所需的数据。这种等待时间极大地影响了处理器的整体性能,因为处理器的执行效率部分取决于它能多快地获得数据。
    为了减轻处理器等待内存访问的延迟,计算机架构设计者开始在处理器与主存之间引入一层高速的缓存存储器。这种缓存通常由静态随机存取存储器(SRAM)构成,具有比动态随机存取存储器(DRAM)更快的访问速度。于是在20世纪60年代,最早的一级缓存(L1 Cache)被引入,用于存储处理器频繁访问的数据和指令。L1 缓存通常直接集成在处理器芯片内,以最小化访问延迟。

2. 缓存的基本概念

• 缓存(Cache):缓存是一块用于存储经常访问的数据的内存区域。当数据请求发出时,系统会首先检查缓存中是否存在该数据,如果存在(称为“缓存命中”),则直接从缓存中返回结果;如果不存在(称为“缓存未命中”),则从后端系统获取数据,并将其存入缓存中以备后用。
• 缓存命中率:缓存命中率是指从缓存中成功获取数据的比例。较高的缓存命中率意味着系统在大多数情况下都可以直接从缓存中获取数据,从而减少对后端系统的访问。

3. 缓存的工作原理

缓存机制的工作流程通常包括以下几个步骤:

  1. 数据请求:客户端或应用程序请求某个数据。
  2. 缓存检查:系统首先检查缓存中是否存在该数据。
  • 如果缓存命中:直接从缓存中返回数据。
  • 如果缓存未命中:从后端系统(如数据库)获取数据。
  1. 缓存更新:如果缓存未命中,系统会将从后端系统获取的数据存入缓存中,以便后续请求可以直接从缓存中获取。
  2. 数据返回:将数据返回给请求方。
    在这里插入图片描述

4. 缓存策略

缓存机制通常涉及多种策略,以确保缓存的高效和合理使用:

  • 缓存失效(Cache Invalidation):当后端数据发生变化时,缓存中的旧数据可能失效。缓存失效策略用于确定何时从缓存中移除或更新数据,以确保缓存中的数据是最新的。
  • 缓存替换策略(Cache Eviction Policy):当缓存空间不足时,需要决定哪些数据应该被移除。常见的替换策略包括:
  • LRU(Least Recently Used):移除最久未使用的数据。
  • LFU(Least Frequently Used):移除使用频率最低的数据。
  • FIFO(First In, First Out):按照数据进入缓存的顺序,最早进入的数据先被移除。
  • 缓存预热(Cache Warming):在系统启动或缓存重建时,预先将一些重要的数据加载到缓存中,以避免缓存未命中带来的性能下降。

MyBatis缓存机制

MyBatis 提供了两级缓存机制:一级缓存(本地缓存)和 二级缓存(全局缓存)。这两个缓存机制可以帮助减少数据库访问次数,提高性能。下面详细介绍这两种缓存机制:

1. 一级缓存(本地缓存)

  • 作用范围:一级缓存是 MyBatis 的默认缓存机制,它作用于 SQL Session 范围内。

  • 特点

    • 默认开启,不需要任何配置。
    • 一级缓存是基于 SQL Session 的,意味着在同一个 SQL Session 中执行的相同查询操作,如果参数相同,MyBatis 会直接从缓存中获取结果,而不会重复查询数据库。
    • 当 SQL Session 关闭时,一级缓存也会被清空。
    • 某些操作(如增、删、改操作)会使一级缓存失效,从而确保缓存数据的一致性。
  • 示例

  SqlSession session = sqlSessionFactory.openSession();
  User user1 = session.selectOne("selectUserById", 1);
  User user2 = session.selectOne("selectUserById", 1);

在这个示例中,user1user2 是在同一个 SQL Session 中执行的查询,如果没有其他干扰操作(如更新),user2 会直接从一级缓存中获取,而不会再次查询数据库。

2. 二级缓存(全局缓存)

  • 作用范围:二级缓存作用于 Mapper 范围内或 全局 范围内。

  • 特点

    • 需要手动配置和开启,默认情况下二级缓存是关闭的。
    • 二级缓存是跨 SQL Session 的,也就是说不同 SQL Session 中对同一数据的查询可以共享缓存。
    • 二级缓存通常存储在内存中,但也可以自定义存储方式(如使用 Redis、Ehcache 等)。
    • 需要在 Mapper 映射文件中通过 <cache> 标签来启用。
    • 与一级缓存一样,执行增、删、改操作会使相关的二级缓存失效。
  • 配置示例
    在 Mapper XML 文件中添加 <cache> 标签来开启二级缓存,缓存配置选项,在 <cache> 标签中可以配置缓存的行为,例如缓存的清除策略、缓存的大小、刷新时间等:

  <mapper namespace="com.example.UserMapper">
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
    
    <select id="selectUserById" resultType="User">
      SELECT * FROM users WHERE id = #{id}
    </select>
  </mapper>

eviction:缓存的淘汰策略,支持以下几种策略:

  • LRU(Least Recently Used):最近最少使用的对象将被清除。
  • FIFO(First In First Out):先进入缓存的对象将被清除。
  • SOFT:软引用,垃圾回收器会根据内存情况决定是否清除缓存。
  • WEAK:弱引用,更积极地清除缓存对象。

flushInterval:刷新间隔时间,单位是毫秒。缓存的数据会在指定时间后被刷新,默认值是没有刷新间隔,只有在执行更新操作时才会清除缓存。

size:缓存的最大对象数目,超出这个数量后,按照淘汰策略清除缓存对象。
readOnly:设置缓存是否为只读模式。只读模式下的缓存对象是不可修改的,这样可以提高缓存的安全性和并发性。默认值为 false。

  • 二级缓存的数据存储

MyBatis 二级缓存数据默认是存储在内存中的,也可以使用第三方缓存框架(如 Ehcache、Redis 等)来存储缓存数据。要使用第三方缓存框架,需要在 标签中配置 type 属性,并指定缓存的实现类:

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
  • 与一级缓存的区别

  • 作用范围:一级缓存作用于单个 SqlSession,二级缓存作用于同一个命名空间下的多个 SqlSession。

  • 缓存级别:一级缓存是 MyBatis 默认开启的,且不需要额外配置。二级缓存需要手动配置并启用。

  • 共享性:一级缓存的数据不能跨 SqlSession 共享,而二级缓存的数据可以跨 SqlSession 共享。

总结

  • 一级缓存:默认开启,作用范围是 SQL Session 内,主要用于减少同一 Session 中的重复查询。
  • 二级缓存:需要手动开启,作用范围是 Mapper 或全局,主要用于减少跨 Session 的重复查询。

需要注意的是

  • 二级缓存适用于查询频繁但更新较少的数据场景,比如字典表、配置表等静态数据。这些数据可以被多个 SqlSession 重复使用,从而减少数据库查询的压力。
  • 由于二级缓存的数据是跨 SqlSession 共享的,可能存在数据一致性问题。当数据在数据库中被更新时,二级缓存中的数据可能变得过时。因此,在涉及频繁更新的数据时,应谨慎使用二级缓存。
  • 缓存穿透是指缓存查询不到数据,导致每次请求都直接访问数据库。为了避免缓存穿透,可以对数据库中不存在的数据进行缓存处理,比如缓存一个空对象或特殊标识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值