MyBatis缓存配置的完整示例,包含一级缓存、二级缓存、自定义缓存策略等核心场景,并附详细注释和总结表格

以下是MyBatis缓存配置的完整示例,包含一级缓存、二级缓存、自定义缓存策略等核心场景,并附详细注释和总结表格:


1. 一级缓存(默认开启)

java 复制代码
// 使用同一SqlSession执行两次查询,自动命中一级缓存
try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user1 = mapper.selectById(1);  // 第一次查询(数据库)
    User user2 = mapper.selectById(1);  // 第二次查询(缓存命中)
    System.out.println(user1 == user2); // 输出:true
}

2. 二级缓存配置(XML方式)

xml 复制代码
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 开启二级缓存 -->
    <cache 
        eviction="FIFO"         <!-- 缓存回收策略:先进先出 -->
        flushInterval="60000"   <!-- 缓存刷新间隔:60秒 -->
        size="512"              <!-- 缓存最大条目数 -->
        readOnly="false"/>      <!-- 是否只读(false允许对象修改) -->
    
    <select id="selectById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

3. 二级缓存注解配置

java 复制代码
// UserMapper.java
@Mapper
@CacheNamespace(
    implementation = EhcacheCache.class, // 使用第三方缓存(如Ehcache)
    eviction = CacheNamespaceEvictionPolicy.FIFO,
    flushInterval = 60000,
    size = 512,
    readWrite = true
)
public interface UserMapper {
    User selectById(Integer id);
}

4. 缓存对象序列化配置

java 复制代码
// User实体类需要实现Serializable接口
public class User implements Serializable {
    private Integer id;
    private String name;
    private transient Integer age; // transient字段不参与序列化
    // 省略getter/setter
}

5. 缓存手动操作示例

java 复制代码
// 清除指定对象缓存
sqlSession.clearCache(); // 清除一级缓存
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.selectById(1); 
sqlSession.commit(); // 触发二级缓存更新

// 清除二级缓存
((org.apache.ibatis.session.Configuration)sqlSession.getConfiguration())
    .getCache("com.example.mapper.UserMapper")
    .clear();

关键技术点总结表

场景 配置方式 适用情况 核心注释
一级缓存 默认开启(SqlSession级别) 单次业务操作内多次查询 不需要配置,关闭需调用sqlSession.clearCache()
二级缓存 <cache>标签或@CacheNamespace 跨SqlSession的全局缓存 必须实现Serializable,需在Mapper配置中显式开启
缓存回收策略 eviction="FIFO/LRU/SID" 控制内存占用 LRU(最近最少使用)最常用
缓存过期 flushInterval="60000" 定时刷新缓存 毫秒单位,配合数据库数据变更频率设置
缓存容量 size="512" 控制内存使用 根据业务数据量合理设置
缓存可写性 readOnly="false" 允许修改缓存对象 readOnly为true时返回对象为不可变副本
第三方缓存 implementation=EhcacheCache 需要分布式缓存 需引入对应依赖并配置缓存实现类

6. 核心配置注意事项:

  1. 序列化要求 :被缓存的对象必须实现Serializable接口
  2. 事务边界:SqlSession关闭或提交(commit)会刷新二级缓存
  3. 并发控制readOnly="true"可避免并发修改问题
  4. 缓存失效:数据更新操作(insert/update/delete)会自动清除相关缓存
  5. 命名空间:二级缓存按Mapper命名空间隔离,需确保唯一性

7. 性能验证示例

java 复制代码
// 验证二级缓存跨SqlSession命中
try (SqlSession session1 = sqlSessionFactory.openSession()) {
    UserMapper mapper1 = session1.getMapper(UserMapper.class);
    User user1 = mapper1.selectById(1); // 数据库查询
}

try (SqlSession session2 = sqlSessionFactory.openSession()) {
    UserMapper mapper2 = session2.getMapper(UserMapper.class);
    User user2 = mapper2.selectById(1); // 二级缓存命中
    System.out.println(user1.equals(user2)); // 输出:true(值相等但对象不同)
}

需要进一步扩展场景(如条件缓存、自定义缓存实现)可补充说明。

相关推荐
OH_TPC4 小时前
【鸿蒙优选三方库】@react-native-ohos/react-native-fast-image:高性能图片加载与缓存组件
缓存·华为·harmonyos·鸿蒙
liangshanbo12154 小时前
手写 Event Emitter(事件发射器)
缓存
数智启示录5 小时前
Apache Kafka Consumer 扩到 40 个仍不提速:Partition 上限锁死有效并行度 【Kafka合集】
数据库·经验分享·分布式·缓存·面试·kafka·apache
2601_962297256 小时前
python自带缓存lru_cache用法及扩展的使用_python
python·缓存·装饰器·lru_cache·my_cache
摇滚侠6 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis MyBatis 简单开发 阅读笔记 39
spring boot·笔记·mybatis
java1234_小锋7 小时前
MyBatis-Plus 3.5.15 已全面支持 Spring Boot 4.0 及 Jackson 3.0
java·spring boot·mybatis
xixingzhe27 小时前
SpringBoot 接口缓存实现
spring boot·后端·缓存
摇滚侠8 小时前
《SpringBoot 3:入门与应用实战》第 13 章 整合 MyBatis 使用 MyBatis-Plus 阅读笔记 40
spring boot·笔记·mybatis
莫得感情 o18 小时前
Redis 05 · 持久化:RDB 与 AOF 怎么保证数据不丢
redis·缓存
curd_boy19 小时前
【Redis】Redis从缓存到AI向量平台
人工智能·redis·缓存