mybatis分布式二级缓存需用redis替代默认perpetualcache;通过实现cache接口、配置启用开关与mapper缓存、引入redis依赖、确保方法允许缓存四步完成集成,实现多节点共享与一致性。

MyBatis 默认的二级缓存是基于 JVM 堆内存的(PerpetualCache),只在单个应用实例内有效;多节点部署时,各节点缓存互不感知,导致数据不一致、重复查库等问题。要实现真正可用的分布式二级缓存,必须将缓存介质从本地内存迁移到共享存储——Redis 是最主流且成熟的选择。
核心思路:用 Redis 替换默认 Cache 实现
MyBatis 的二级缓存机制高度可扩展,其核心是 org.apache.ibatis.cache.Cache 接口。只要提供一个 Redis 版本的实现类(如 RedisCache),并在 Mapper 层声明使用它,整个查询链路就能自动把缓存读写转向 Redis。
- 不需要修改业务代码或 SQL 逻辑,对开发者透明
- 缓存 key 自动按 Mapper 全限定名 + SQL 参数哈希生成,天然支持多 Mapper 隔离
- 所有节点共用同一套 Redis 实例,天然解决缓存共享与一致性问题
关键配置步骤
分四步完成集成,缺一不可:
-
启用全局二级缓存开关:在 MyBatis 配置中设置
cache-enabled: true(YAML)或<setting name="cacheEnabled" value="true"></setting>(XML) -
为指定 Mapper 启用缓存:在接口上加
@CacheNamespace(implementation = RedisCache.class),或在Mapper.xml中添加<cache type="com.example.RedisCache"></cache> -
引入 Redis 客户端依赖:根据技术栈选型,常见组合有:
- Jedis +
mybatis-redis(轻量,适合简单场景) - Spring Data Redis + 自定义
RedisCache(更灵活,易集成 Spring 事务与序列化) - Redisson + 分布式锁增强(适合高并发、需强一致性的场景)
- Jedis +
-
确保查询方法允许使用缓存:Mapper 方法默认启用缓存,但若显式设置了
@Options(useCache = false)则会跳过;增删改操作会自动清空对应 namespace 缓存
自定义 RedisCache 注意要点
手写实现类时,这几个细节直接影响稳定性和性能:
-
key 命名规范:建议统一前缀(如
mybatis:UserMapper:)+ Mapper ID + MD5(参数),避免 key 冲突和可读性差 - 序列化方式:推荐使用 JSON(Jackson)或 JDK 序列化,注意实体类必须可序列化;若用 StringRedisTemplate,需自行处理对象转字符串
-
过期策略:不能依赖 Redis 全局 TTL,应在
putObject()中显式调用expire(),例如缓存 10 分钟:jedis.expire(key, 600) -
线程安全:MyBatis 会多线程调用
getObject()/putObject(),内部无需加锁(Redis 服务端天然串行),但连接获取(如 JedisPool)需线程安全
验证是否生效
最直接的方式是观察 SQL 打印日志:
- 首次查询:输出 SQL 日志 → 查询数据库 → 写入 Redis
- 第二次相同查询(跨 SqlSession):无 SQL 日志 → 直接从 Redis 取值返回
- 执行同 namespace 的 INSERT/UPDATE/DELETE:自动触发
clear(),对应 Redis key 被删除
也可用 redis-cli keys "mybatis:*" 查看缓存是否存在,或用监控工具观察 Redis 的 get/set QPS 变化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











