mybatis分布式二级缓存需用redis替代hashmap实现,核心包括:显式开启cacheenabled、mapper级配置rediscache、加命名空间前缀隔离key、写操作清缓存+ttl过期+业务维度批量清理、统一json序列化及null值处理。

MyBatis 默认二级缓存是本地 HashMap 实现,只在单 JVM 内生效,无法应对分布式部署。要让多个服务实例共享缓存、统一失效、避免脏数据,必须用 Redis 替代,并重点设计失效策略——这不是简单换一个缓存类,而是围绕数据一致性重构缓存生命周期。
启用分布式二级缓存的基础配置
先确保 MyBatis 二级缓存开关已打开(默认 true,但建议显式确认):
- 全局开启:
<setting name="cacheEnabled" value="true"></setting>(在 mybatis-config.xml 或 Spring Boot 的mybatis.configuration.cache-enabled=true) - Mapper 级启用:在对应 Mapper 接口或 XML 中声明使用 RedisCache
- 接口方式:
@CacheNamespace(implementation = RedisCache.class) - XML 方式:
<cache type="org.mybatis.caches.redis.RedisCache"></cache>
让缓存键可区分、可管理
多个服务或不同环境共用同一 Redis 实例时,缓存键容易冲突。必须做命名空间隔离:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在
redis.properties(或 Spring Boot 的application.yml)中设置前缀:redis.cache.prefix=myapp:user: - 自定义
RedisCache子类,重写getId()方法,将 Mapper 全限定名 + 自定义前缀拼入缓存 key - 避免直接用原始 SQL 或参数哈希作为 key,应包含业务语义(如
user:1001),便于人工排查和主动清理
控制缓存失效的三种核心方式
分布式环境下,不能依赖“自动过期”兜底,必须结合业务主动干预:
-
写操作触发清除:在 insert/update/delete 方法上加
@Options(flushCache = true),或在 XML 的<insert></insert>标签里设flushCache="true",确保修改后清掉关联缓存 -
带 TTL 的自动过期:通过
redis.cache.expiration=600000(单位毫秒)配置默认过期时间;也可在自定义 RedisCache 构造时传入不同 TTL,对热点数据设长过期,冷数据设短过期 -
按业务维度批量清理:例如用户信息变更时,用 Redis 的
KEYS user:*:profile+DEL清除一组 key;生产环境建议改用 SCAN 避免阻塞,或用 Hash 结构聚合同类缓存再整体删除
保障序列化与数据一致性
Redis 是网络传输介质,Java 对象必须可序列化,且序列化方式影响性能与兼容性:
- 实体类必须实现
Serializable,否则 RedisCache 写入时会抛异常 - 默认 Java 序列化效率低、体积大、升级易不兼容;推荐替换为 JSON 序列化(如 Jackson 或 FastJSON),需继承
RedisCache并重写serialize/deserialize方法 - 注意 null 值处理:MyBatis 默认不缓存 null 查询结果,若业务需缓存空结果防穿透,应在自定义 Cache 实现中放开限制,并配合布隆过滤器使用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










