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(值相等但对象不同)
}

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

相关推荐
YOU OU8 小时前
Redis基础常识与命令
数据库·redis·缓存
吳所畏惧12 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
Y38153266217 小时前
SERP API + Redis 缓存层:4 种方案对比与选型
数据库·redis·缓存
海兰19 小时前
【高速缓存】RedisVL 高级查询(全文搜索、混合搜索和 多向量搜索)
数据库·人工智能·redis·缓存
流星白龙1 天前
【Redis】4.基本全局命令
数据库·redis·缓存
流星白龙1 天前
【Redis】3.Redis安装与命令行客户端
数据库·redis·缓存
我不想名字重复2 天前
redis缓存和数据库数据保持一致
数据库·redis·缓存
时空无限2 天前
vllm 大模型启动缓存相关环境变量 export
linux·缓存·vllm
流星白龙2 天前
【Redis】6.计数其他命令
数据库·redis·缓存
天若有情6732 天前
SpringBoot4 + MyBatis 前后端分离实战|从零实现坏习惯管理系统,支持局域网手机访问CRUD
智能手机·mybatis