Mybatis的一级、二级缓存?Mybatis的二级缓存什么时候会清理缓存中的数据?


MyBatis 一级缓存与二级缓存详解

MyBatis的一级缓存是基于PerpetualCache的HashMap本地缓存,作用域为Session,默认开启。二级缓存需要单独开启,作用域为Namespace或mapper,默认也是采用PerpetualCache,HashMap存储。

一、一级缓存(Local Cache)

  • 作用范围SqlSession 级别,默认开启。
  • 生命周期
    • 缓存数据仅在当前 SqlSession 有效。
    • SqlSession 关闭或执行 commit()rollback() 时,缓存清空。
  • 失效场景
    1. 执行 INSERT/UPDATE/DELETE 操作(无论是否提交)。
    2. 手动调用 sqlSession.clearCache()
  • 特点
    • 减少同一会话内重复查询的数据库访问。
    • 不支持跨会话共享,易受局部操作影响失效。

二、二级缓存(Global Cache)

  • 作用范围Mapper 级别(跨 SqlSession),需显式开启。
  • 配置方式
    在 Mapper XML 中添加 <cache /> 标签,或通过 @CacheNamespace 注解启用。
    xml
    复制代码
    <!-- Mapper.xml 中启用二级缓存 --> <mapper namespace="com.example.UserMapper"> <cache eviction="LRU" flushInterval="60000" size="1024"/> </mapper>
  • 存储机制
    • 缓存数据序列化后存储(实体类需实现 Serializable 接口)。
    • 不同 Mapper 的缓存相互隔离。

三、二级缓存的清理时机

  1. 执行更新操作(INSERT/UPDATE/DELETE)

    • 同一 Mapper 的任意更新操作会触发二级缓存清空,确保数据一致性。
    • 示例UserMapper.updateUser() 执行后,UserMapper 的二级缓存失效。
  2. 手动调用清理方法

    • 通过 SqlSession 调用 clearCache() 仅清理一级缓存。
    • 清理二级缓存:需获取 Cache 对象并调用 clear()
      java
      复制代码
      sqlSession.getMapper(UserMapper.class); // 获取 Mapper Cache cache = sqlSession.getConfiguration().getCache("com.example.UserMapper"); cache.clear(); // 手动清理二级缓存
  3. 达到刷新间隔(flushInterval)

    • 若配置 flushInterval="60000",则每隔 60 秒自动清空缓存。
    • 适用场景:对实时性要求不高的数据(如配置表),定期刷新缓存。
  4. 缓存淘汰策略触发

    • 当缓存对象数量超过 size 限制时,按策略(如 LRUFIFO)移除数据。
    • 常见策略
      • LRU(最近最少使用,默认)
      • FIFO(先进先出)
      • SOFT(软引用,依赖 GC)
      • WEAK(弱引用,依赖 GC)
  5. 事务提交(默认配置)

    • 若未设置 flushCache="false",事务提交时自动清空关联 Mapper 的二级缓存。
    • 注意:全局缓存可能导致跨会话数据不一致,需结合业务场景谨慎使用。

四、二级缓存注意事项

  1. 数据一致性风险

    • 多表关联查询时,若其他 Mapper 更新数据,当前 Mapper 的缓存不会自动失效。
    • 解决方案:通过 <cache-ref /> 关联其他 Mapper 的缓存,或手动清理。
  2. 序列化要求

    • 缓存对象需实现 Serializable 接口,否则可能抛出序列化异常。
  3. 适用场景

    • 读多写少的数据(如基础配置、历史记录)。
    • 避免用于频繁更新的数据(如订单状态),防止缓存频繁失效。

五、缓存对比总结

特性一级缓存二级缓存
作用域SqlSession 内部Mapper 级别,跨 SqlSession
存储位置内存(未序列化)序列化后存储(可配置 Redis 等分布式缓存)
默认状态启用需显式配置
清理触发DML 操作、会话关闭DML 操作、定时刷新、手动清理
性能影响低开销,仅会话内复用需序列化,跨会话共享,可能影响性能

六、配置优化建议

  • 合理设置 flushIntervalsize:根据数据更新频率和内存容量调整。
  • 避免滥用二级缓存:优先通过业务层缓存(如 Redis)管理高频跨表数据。
  • 监控缓存命中率:结合日志或监控工具分析缓存效果,及时调整策略。

理解 MyBatis 缓存机制及清理逻辑,有助于在高并发场景下平衡性能与数据一致性。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
李南北
下载 APP