mybatis二级缓存需用redis替代默认hashmap实现分布式共享,关键在于整合生命周期、序列化与失效策略;使用mybatis-redis模块并配置redis.properties,开启cacheenabled且在mapper中声明rediscache,建议自定义json序列化及前缀隔离缓存键。

MyBatis 默认的二级缓存基于本地 HashMap,仅限单机有效,无法满足分布式部署场景。要支持多实例共享、高并发读取和数据一致性,必须用 Redis 这类中心化缓存组件替代原生缓存。重构的关键不是“替换一个类”,而是打通 MyBatis 缓存生命周期与 Redis 的读写、序列化、连接管理及失效策略。
引入标准依赖并配置基础连接
使用官方维护的 mybatis-redis 模块最稳妥,它已封装 Jedis 初始化、属性加载和基本操作逻辑:
- 添加 Maven 依赖(注意版本兼容性,推荐
1.0.0-beta2或更高稳定版):
org.mybatis.caches
mybatis-redis
1.0.0-beta2 - 在
resources/目录下新建redis.properties(路径和文件名不可更改,源码硬编码读取):
redis.host=localhost
redis.port=6379
redis.connectionTimeout=5000
redis.password=
redis.database=0 - 确保 Redis 服务已启动且网络可达;Spring Boot 项目还需额外引入
spring-boot-starter-data-redis以支持自动配置(非必须,但利于统一连接池管理)。
启用全局二级缓存并绑定 Redis 实现
MyBatis 需明确知道“缓存开关已开”且“该用哪个实现”。两处配置缺一不可:
- 在
mybatis-config.xml或 Spring Boot 的application.yml中开启缓存总开关:
或:
mybatis:
configuration:
cache-enabled: true - 在具体 Mapper XML 文件顶部声明缓存类型:
也可用注解方式:
@Mapper
@CacheNamespace(implementation = RedisCache.class)
public interface UserMapper { ... }
定制缓存行为:序列化、命名空间与失效控制
开箱即用的 RedisCache 使用 JDK 序列化,不推荐用于生产。建议自定义实现以支持 JSON、避免跨语言/升级兼容问题,并隔离不同 Mapper 的缓存键:
- 继承
org.apache.ibatis.cache.Cache接口,注入RedisTemplate(推荐 Lettuce + JSON 序列化); - 构造时将
id(即 Mapper 全限定名)作为 Redis Key 前缀,例如:
key = "cache:" + this.id + ":" + key.hashCode(); - 重写
putObject时设置合理过期时间(如 5–30 分钟),避免无限堆积; - 在
clear()方法中慎用flushDB(),应改用前缀匹配删除(scan + del)或按命名空间清空,防止误删其他业务缓存。
验证与协同注意事项
缓存生效需满足前提条件,否则容易误判为“没起作用”:
- 两次查询必须由**不同 SqlSession** 发起(一级缓存会拦截,导致永远查不到二级);
- Mapper 接口方法必须声明
useCache="true"(XML 中默认为 true,但显式标注更清晰); - 执行更新操作(
insert/update/delete)后,MyBatis 会自动清空当前 Mapper 对应的二级缓存——前提是这些语句与该<cache></cache>在同一 namespace 下; - 开启 MyBatis 日志(如
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl),观察是否出现Cache Hit Ratio统计,以及 Redis 中是否生成形如-123456789:com.example.mapper.UserMapper.selectList的 key。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











