IIWAB mybatis缓存 - IIWAB

mybatis缓存

IIWAB 6小时前 ⋅ 5 阅读

MyBatis 提供了缓存机制来提升数据库查询性能,避免重复执行相同的 SQL 语句,减轻数据库压力。其缓存分为一级缓存二级缓存,两者的作用范围和生命周期不同。

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

  • 作用范围:仅限于当前 SqlSession(会话),即同一个 SqlSession 内的查询会共享缓存。
  • 生命周期:随 SqlSession 的创建而创建,随 SqlSession 的关闭(close())或提交(commit()/rollback())而清空。
  • 默认行为:一级缓存默认开启,无需额外配置。
  • 工作原理
    • 当执行查询时,MyBatis 会先在一级缓存中查找是否存在相同的查询结果(通过 Mapper ID + SQL 语句 + 参数 + 分页信息 等作为缓存键)。
    • 若存在,则直接返回缓存数据;若不存在,则执行 SQL 并将结果存入一级缓存。
    • 若在同一个 SqlSession 内执行了 增删改操作insert/update/delete),MyBatis 会自动清空一级缓存,避免脏数据。

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

  • 作用范围:跨 SqlSession 共享,作用于整个 Mapper 接口(或 Mapper.xml),即同一个 Mapper 的所有 SqlSession 共享缓存。
  • 生命周期:随应用启动而创建,随应用关闭而销毁(可通过配置调整过期策略)。
  • 开启方式:默认关闭,需手动配置:
    1. MyBatis 全局配置文件(mybatis-config.xml)中开启二级缓存总开关(默认已开启,可省略):
      <settings>
        <setting name="cacheEnabled" value="true"/>
      </settings>
      
    2. 在需要使用二级缓存的 Mapper.xml 中添加 <cache/> 标签(或在接口类上添加 @CacheNamespace 注解):
      <!-- Mapper.xml 中配置 -->
      <mapper namespace="com.example.UserMapper">
        <cache 
          eviction="LRU"    <!-- 缓存回收策略:LRU(默认,最近最少使用)、FIFO、SOFT、WEAK -->
          flushInterval="60000"  <!-- 自动刷新时间(毫秒),默认不刷新 -->
          size="1024"       <!-- 最大缓存对象数量,默认 1024 -->
          readOnly="false"/> <!-- 是否只读:false(默认,可序列化对象)、true(返回缓存对象的引用) -->
      </mapper>
      
  • 注意事项
    • 二级缓存的对象需实现 Serializable 接口(当 readOnly=false 时,避免序列化失败)。
    • Mapper 中某条 SQL 不需要使用二级缓存,可通过 useCache="false" 禁用:
      <select id="getUser" resultType="User" useCache="false">
        SELECT * FROM user WHERE id = #{id}
      </select>
      
    • 执行增删改操作时,MyBatis 会自动清空当前 Mapper 的二级缓存(可通过 flushCache="false" 关闭自动清空,但不推荐,可能导致脏数据)。

3. 一级缓存与二级缓存的执行顺序

当查询执行时,MyBatis 会先检查二级缓存,若未命中则检查一级缓存,若仍未命中则执行 SQL 查询,查询结果会依次存入一级缓存和二级缓存(若开启)。

4. 缓存的适用场景

  • 适合缓存查询频率高、数据变化少的场景(如字典表、配置表)。
  • 不适合缓存实时性要求高、数据频繁变化的场景(如订单表、库存表)。

总结

  • 一级缓存:默认开启,SqlSession 级,随会话销毁,无需配置。
  • 二级缓存:需手动开启,Mapper 级,全局共享,需注意序列化和脏数据问题。

全部评论: 0

    我有话说: