的作用是让多个mapper共享同一二级缓存实例,避免重复缓存、节省内存并保证一致性;它引用已配置的mapper的缓存对象,要求namespace完全匹配且不能与共存。

cache-ref 的作用是让多个 Mapper 共用同一个二级缓存实例,避免重复缓存相同数据,节省内存并保证缓存一致性。
cache-ref 的核心用途
它不是新建缓存,而是“引用”另一个已配置 <cache></cache> 的 Mapper 的缓存对象。被引用的 Mapper 必须已声明 <cache></cache>,否则启动会报错。
- 适用于多张表逻辑强关联、常联合查询的场景(如
UserMapper和UserProfileMapper) - 所有引用同一缓存的 Mapper,增删改操作都会触发该缓存整体清空(即共用 flush 行为)
- 缓存 key 的命名仍基于各自 namespace + SQL ID,不会冲突,但底层存储是同一 Cache 实例
配置步骤与写法
只需在需要共享缓存的 Mapper XML 文件中,用 <cache-ref></cache-ref> 替代 <cache></cache>,并指定目标 namespace:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
<mapper namespace="com.example.order.OrderMapper"><cache-ref namespace="com.example.user.UserMapper"></cache-ref><select id="selectOrderWithUser" resulttype="OrderVo">
SELECT o.*, u.name FROM orders o JOIN users u ON o.user_id = u.id
</select></mapper>
- 确保
com.example.user.UserMapper的 XML 中已定义<cache></cache>或完整<cache></cache>配置 - namespace 值必须完全匹配,包括包路径和类名,大小写敏感
- 不能同时存在
<cache></cache>和<cache-ref></cache-ref>,否则解析失败
注意事项与常见问题
共享缓存看似简单,但实际使用需警惕副作用:
- 只要任意一个引用该缓存的 Mapper 执行了
insert/update/delete,整个共享缓存会被清空(即使操作的是另一张表) - 实体类必须实现
Serializable(若readOnly="false",即默认读写模式) - 不支持跨 MyBatis SqlSessionFactory 实例共享;仅限同一应用内、同一工厂创建的 SqlSession
- 调试时可通过日志开启
org.apache.ibatis.cache级别观察缓存命中/清空行为
什么时候该用 cache-ref 而不是独立 cache
典型适用场景有两类:
- 主子表或宽表拆分:如
ProductMapper和ProductDetailMapper总是一起查,且更新频率一致 - 读多写少+强一致性要求:比如字典类数据分散在多个 Mapper 中(
StatusMapper、TypeMapper),统一由一个缓存管理更安全
如果各 Mapper 数据更新节奏差异大,或存在部分只读、部分高频变更的情况,建议各自配置独立 <cache></cache>,避免互相干扰。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










