当前位置: 首页 > news >正文

mybatisplus 配置二级缓存

MyBatis-Plus(简称 MP)作为 MyBatis 的增强工具,完全兼容 MyBatis 的二级缓存机制,同时提供了更便捷的配置方式。以下是基于 MyBatis-Plus 的二级缓存配置全指南,包含基础配置、高级特性及实战示例:

一、二级缓存核心依赖

确保项目中包含 MyBatis-Plus 及缓存相关依赖(以 Spring Boot 为例):

<!-- MyBatis-Plus核心依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version>
</dependency><!-- 可选:Redis缓存(分布式环境必备) -->
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-redis</artifactId><version>1.0.0-beta2</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

二、基础配置(本地缓存)

适用于单机环境,使用 MyBatis 默认的内存缓存(PerpetualCache)。

2.1 全局开启二级缓存

application.yml中开启全局缓存开关(MyBatis 默认开启,建议显式配置):

mybatis-plus:configuration:cache-enabled: true  # 全局启用二级缓存(默认为true)mapper-locations: classpath*:mapper/**/*.xml  # 指定Mapper.xml路径
2.2 实体类实现序列化

二级缓存存储对象需支持序列化(避免缓存失败):

package com.example.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;@Data
public class User implements Serializable {private static final long serialVersionUID = 1L;  // 必须添加序列化版本号@TableId(type = IdType.AUTO)private Long id;private String username;private String email;private LocalDateTime createTime;
}
2.3 在 Mapper 中开启二级缓存

有两种方式配置 Mapper 级别的二级缓存,根据项目风格选择:

方式 1:XML 配置(推荐,支持更多缓存参数)

在对应的UserMapper.xml中添加<cache>标签:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.example.mapper.UserMapper"><!-- 配置二级缓存 --><cache eviction="LRU"        <!-- 缓存淘汰策略:LRU(最近最少使用) -->flushInterval="60000" <!-- 自动刷新间隔(60秒) -->size="1024"           <!-- 最大缓存对象数 -->readOnly="false"/>    <!-- 非只读(需序列化) --><!-- MP自动生成的SQL会自动使用缓存,自定义SQL需显式配置 --><select id="selectById" resultType="com.example.entity.User">SELECT id, username, email, create_time AS createTime FROM t_user WHERE id = #{id}</select>
</mapper>
方式 2:注解配置(简化配置,适合无 XML 场景)

在 Mapper 接口上使用@CacheNamespace注解:

package com.example.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.cache.impl.PerpetualCache;// 注解方式开启二级缓存,默认使用PerpetualCache
@CacheNamespace(eviction = LruCache.class,  // 淘汰策略:LRUflushInterval = 60000,      // 刷新间隔60秒size = 1024,                // 最大缓存数readWrite = true            // 读写模式(非只读)
)
public interface UserMapper extends BaseMapper<User> {// 继承BaseMapper的方法会自动使用缓存
}

三、高级配置(分布式缓存,Redis 为例)

单机缓存无法满足分布式环境需求,需集成 Redis 实现缓存共享。

3.1 配置 Redis 连接

创建redis.properties(src/main/resources/):

redis.host=localhost
redis.port=6379
redis.timeout=2000
redis.password=  # 无密码则留空
redis.database=0
redis.default.expiration=1800000  # 缓存默认过期时间(30分钟)
3.2 配置 Mapper 使用 Redis 缓存
方式 1:XML 配置指定 Redis 缓存类型
<mapper namespace="com.example.mapper.UserMapper"><!-- 使用Redis作为二级缓存 --><cache type="org.mybatis.caches.redis.RedisCache"><property name="eviction" value="LRU"/><property name="flushInterval" value="60000"/><property name="size" value="1024"/></cache>
</mapper>
方式 2:注解配置自定义 Redis 缓存
package com.example.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;
import org.apache.ibatis.annotations.CacheNamespace;
import org.mybatis.caches.redis.RedisCache;// 注解方式指定Redis缓存
@CacheNamespace(implementation = RedisCache.class)
public interface UserMapper extends BaseMapper<User> {
}
3.3 自定义 Redis 缓存(可选,优化序列化)

默认 Redis 缓存使用 Java 序列化,性能较差,可自定义 JSON 序列化:

package com.example.cache;import com.fasterxml.jackson.databind.ObjectMapper;
import org.mybatis.caches.redis.RedisCache;
import java.util.concurrent.locks.ReadWriteLock;public class JsonRedisCache extends RedisCache {private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();public JsonRedisCache(String id) {super(id);}@Overridepublic void putObject(Object key, Object value) {try {// 序列化为JSON字符串String jsonValue = OBJECT_MAPPER.writeValueAsString(value);super.putObject(key, jsonValue);} catch (Exception e) {throw new RuntimeException("缓存序列化失败", e);}}@Overridepublic Object getObject(Object key) {try {String jsonValue = (String) super.getObject(key);if (jsonValue != null) {// 反序列化为目标对象(根据实际类型调整)return OBJECT_MAPPER.readValue(jsonValue, User.class);}} catch (Exception e) {throw new RuntimeException("缓存反序列化失败", e);}return null;}// 禁用默认锁(Redis本身是单线程,无需额外锁)@Overridepublic ReadWriteLock getReadWriteLock() {return null;}
}

使用自定义缓存:

<cache type="com.example.cache.JsonRedisCache"/>

四、缓存细粒度控制

MyBatis-Plus 支持对单个方法配置缓存策略,覆盖全局设置。

4.1 禁用特定查询的缓存
<!-- XML方式:当前查询不使用二级缓存 -->
<select id="selectByUsername" resultType="User" useCache="false">SELECT * FROM t_user WHERE username = #{username}
</select>
// 注解方式:使用@Options禁用缓存
import org.apache.ibatis.annotations.Options;public interface UserMapper extends BaseMapper<User> {@Options(useCache = false)User selectByUsername(String username);
}
4.2 强制刷新缓存
<!-- 执行该查询前清空缓存 -->
<select id="selectLatestUsers" resultType="User" flushCache="true">SELECT * FROM t_user ORDER BY create_time DESC LIMIT 10
</select>
// 注解方式强制刷新
@Options(flushCache = Options.FlushCachePolicy.TRUE)
List<User> selectLatestUsers();

五、验证二级缓存生效

编写测试类验证缓存是否生效:

package com.example.test;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Objects;@Slf4j
@SpringBootTest
public class MpCacheTest {@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Testpublic void testSecondLevelCache() {// 第一次查询:缓存未命中,查数据库try (SqlSession session1 = sqlSessionFactory.openSession()) {UserMapper mapper1 = session1.getMapper(UserMapper.class);User user1 = mapper1.selectOne(new QueryWrapper<User>().eq("id", 1L));log.info("第一次查询结果:{}", user1);} // 会话关闭,数据存入二级缓存// 第二次查询:命中二级缓存try (SqlSession session2 = sqlSessionFactory.openSession()) {UserMapper mapper2 = session2.getMapper(UserMapper.class);User user2 = mapper2.selectOne(new QueryWrapper<User>().eq("id", 1L));log.info("第二次查询结果:{}", user2);}}
}

预期日志(第二次查询无 SQL 输出,证明命中缓存):

第一次查询结果:User(id=1, username=test, ...)
==>  Preparing: SELECT ... FROM t_user WHERE (id = ?)
==> Parameters: 1(Long)
<==      Total: 1第二次查询结果:User(id=1, username=test, ...)  // 无SQL执行,命中二级缓存

六、注意事项

  1. BaseMapper 方法的缓存行为
    MyBatis-Plus 自动生成的 CRUD 方法(如selectByIdupdateById)会自动遵循缓存配置,更新操作会触发缓存清空。

  2. 分页插件与缓存
    使用Page分页查询时,缓存键会包含分页参数(pageNumpageSize),确保不同分页的结果正确缓存。

  3. 多表关联查询
    若 Mapper 中包含多表关联查询,建议使用@CacheNamespaceRef关联相关 Mapper,确保更新任一表时同步清空缓存:

    @CacheNamespaceRef(UserMapper.class)  // 共享UserMapper的缓存
    public interface UserOrderMapper extends BaseMapper<UserOrder> {
    }
    
  4. 避免缓存超大结果集
    对返回大量数据的查询(如selectList()无限制条件),建议禁用缓存(useCache=false),避免内存溢出。

总结

MyBatis-Plus 配置二级缓存的核心是:

  1. 全局开启cache-enabled: true
  2. 实体类实现Serializable
  3. 在 Mapper 中通过 XML 或注解配置<cache>/@CacheNamespace
  4. 分布式环境替换为 Redis 缓存

通过合理配置,可充分利用二级缓存减少数据库访问,同时需平衡缓存命中率与数据一致性,避免脏读问题。

http://www.dtcms.com/a/351504.html

相关文章:

  • 【系统编程】线程简介
  • 【人工智能】2025年AI代理开源革命:社区驱动的智能体生态重塑未来
  • Linux--seLinux的概述
  • FRET、PLA、Co-IP和GST pull-down有何区别? 应该如何选择?
  • 原型模式系统开发中的原型分类全景:水平、垂直、抛弃式与演化式
  • nvm切换node版本之后报错,无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
  • 嵌入式C语言进阶:结构体封装函数的艺术与实践
  • IUV5G专网排障(上)
  • 支持向量机(SVM)学习笔记
  • SOME/IP服务发现PRS_SOMEIPSD_00277的解析
  • 服务器数据恢复—热备盘上线失败如何恢复数据?
  • 【Android】webview强制Crash后再自恢复设计
  • 服务器初始化
  • 影响服务器托管费用的因素​
  • ROS2 Helloworld 入门——包含完整pdf手册
  • Linux驱动开发笔记(九)——内核定时器
  • CSS 优先级:公司组织架构模型
  • css3背景线性渐变:linear-gradient
  • 基于Python+MySQL实现物联网引论课程一个火警报警及应急处理系统
  • 面向 6G 网络的 LLM 赋能物联网:架构、挑战与解决方案
  • 相机激光安全等级和人眼安全
  • 第九届MathorCup高校数学建模挑战赛-D题:钢水“脱氧合金化”配料方案的优化
  • 五自由度磁悬浮轴承同频振动抑制:从机理拆解到传递函数验证的核心方案
  • 【图像算法 - 24】基于深度学习与 OpenCV 实现人员跌倒识别系统(目标检测方案 - 跌倒即目标)
  • Baumer高防护相机如何通过YoloV8深度学习模型实现形状检测器的使用(YOLOv8 Shape Detector)
  • 无人机航拍数据集|第32期 无人机采矿区作业目标检测YOLO数据集202张yolov11/yolov8/yolov5可训练
  • GaussDB 数据库架构师修炼(十八) SQL引擎-计划管理-SPM
  • Windows MCP 安装教程:让 AI 代理与 Windows 系统无缝交互
  • plantsimulation知识点 RGV小车前端与后端区别
  • 数字营销岗位需要具备的能力有哪些