说说 MyBatis 的缓存机制?

最后更新:1/12/2026

AI 助手

会员专享功能

只有会员才能使用 AI 生成答案功能。 立即升级

Other Answers (1)

Generated by DeepSeek V3

MyBatis 的缓存机制

MyBatis 提供了强大的缓存机制来提高数据库访问性能,主要分为一级缓存和二级缓存两个层级。

一级缓存(Local Cache)

一级缓存是 SqlSession 级别的缓存,默认开启且无法关闭。

特点:

  • 同一个 SqlSession 中执行相同的 SQL 查询时,会直接从缓存中获取结果
  • 执行 INSERT/UPDATE/DELETE 操作或调用 clearCache() 方法会清空一级缓存
  • 生命周期与 SqlSession 相同

代码示例:

java
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
    // 第一次查询,会访问数据库
    User user1 = mapper.selectUserById(1);
    
    // 第二次查询相同SQL,直接从缓存获取
    User user2 = mapper.selectUserById(1);
    
    // user1 == user2 为 true
} finally {
    sqlSession.close();
}

二级缓存(Second Level Cache)

二级缓存是 Mapper 级别的缓存,多个 SqlSession 可以共享缓存数据。

特点:

  • 需要手动配置开启(默认关闭)
  • 作用域为 Mapper 的 namespace
  • 执行 INSERT/UPDATE/DELETE 操作会清空二级缓存
  • 可配置多种缓存实现(如 Ehcache、Redis 等)

启用步骤:

  1. 在 MyBatis 配置文件中启用二级缓存:
xml
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
  1. 在 Mapper XML 中配置缓存:
xml
<cache/>
  1. 实体类需要实现 Serializable 接口

高级配置示例:

xml
<cache 
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

缓存策略(eviction):

  • LRU - 最近最少使用(默认)
  • FIFO - 先进先出
  • SOFT - 软引用
  • WEAK - 弱引用

缓存执行顺序

当开启二级缓存时,MyBatis 的查询顺序为:

  1. 先查二级缓存
  2. 二级缓存没有则查一级缓存
  3. 一级缓存没有才查询数据库

注意事项

  1. 一级和二级缓存都是基于 PerpetualCache 的简单实现,没有过期策略
  2. 分布式环境下,简单的二级缓存实现会有一致性问题
  3. 对于频繁修改的数据,缓存可能反而降低性能
  4. 可以通过 <select useCache="false"><insert flushCache="true"> 细粒度控制缓存行为

自定义缓存

MyBatis 允许集成第三方缓存实现:

xml
<cache type="com.domain.something.MyCustomCache"/>

自定义缓存需要实现 org.apache.ibatis.cache.Cache 接口。

MyBatis 的缓存机制提供了灵活的性能优化手段,但需要根据实际业务场景合理配置以避免数据一致性问题。