MyBatis-Plus缓存机制深度解析与SpringBoot整合实战

发布于:2025-03-26 ⋅ 阅读:(21) ⋅ 点赞:(0)

一、MyBatis-Plus缓存机制全景解析

MyBatis-Plus在MyBatis原生缓存基础上进行了深度增强,形成了多层次的缓存体系:

1. 缓存层级架构

应用层
├── MP扩展缓存(多租户/逻辑删除)
├── 二级缓存(Mapper级别,跨Session共享)
└── 一级缓存(SqlSession级别,默认开启)

2. 核心优势对比

特性 MyBatis原生 MyBatis-Plus增强
配置方式 XML为主 注解+配置类
自动刷新 手动控制 内置智能刷新逻辑
多租户支持 内置SQL解析缓存
监控能力 基础 增强的统计功能

二、SpringBoot整合完整配置指南

1. 基础配置(application.yml)

mybatis-plus:
  configuration:
    cache-enabled: true   # 开启二级缓存
    local-cache-scope: session  # 一级缓存作用域(SESSION/STATEMENT)
  global-config:
    db-config:
      logic-delete-field: deleted  # 逻辑删除字段名
      logic-not-delete-value: 0    # 未删除标记值

2. 实体类缓存注解配置

/**
 * 用户实体类
 * @CacheNamespace 声明使用自定义Redis缓存实现
 */
@TableName("sys_user")
@CacheNamespace(
    implementation = MybatisRedisCache.class,  // 缓存实现类
    eviction = MybatisRedisCache.class,       // 淘汰策略类
    size = 1000,                             // 缓存最大容量
    readWrite = true                         // 读写模式
)
public class User implements Serializable {
   
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @TableField(condition = SqlCondition.LIKE)
    private String username;
    
    @TableLogic
    private Integer deleted;  // 逻辑删除标记字段
}

3. 自定义Redis缓存实现(带注释版)

/**
 * 自定义Redis缓存实现类
 */
public class MybatisRedisCache implements Cache {
   
    // 读写锁保证线程安全
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final String id;  // Mapper namespace标识
    private final RedisTemplate<String, Object> redisTemplate;

    public MybatisRedisCache(String id) {
   
        this.id = id;
        // 从Spring容器获取RedisTemplate实例
        this.redisTemplate = (RedisTemplate<String, Object>) 
            SpringContextHolder.getBean("redisTemplate");
    }

    @Override
    public String getId() {
   
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
   
        // 设置缓存,有效期2小时
        redisTemplate.opsForValue().set(
            key.toString(), 
            value, 
            2, 
            TimeUnit.HOURS
        );
    }

    @Override
    public Object getObject(Object key) {
   
        // 从Redis获取缓存
        return redisTemplate.opsForValue().get</