Mybatis对象自动缓存插件
文章目录
介绍
自动将baseMapper.selectById(id)、lambdaQuery().eq(Entity::getId, id)、listByIds(ids)等方式通过主键或主键集合查询的对象结果,自动将查询结果缓存到Redis中。
缓存对象默认1天(上下浮动10%),数据库中没有的数据也会缓存一个NULL值(1分钟有效期)。避免缓存穿透和雪崩。
数据删除、更新时会自动清除缓存(removeById、updateById、update等方法,如果使用lambdaUpdate则仅限于通过主键方式更新lambdaUpdate().eq(BookEmbeddings::getId, 8)。
源码
原理
- 实现
org.apache.ibatis.plugin.Interceptor接口,拦截select、update操作。 - 分析
MappedStatement的参数,找到操作的对象类型和主键。 - 对于查询操作,使用
RedisTemplate缓存查询结果。 - 对于更新操作,清除相关的缓存。
- 支持批量查询和单个查询,自动处理主键集合。使用mget批量获取redis中已有缓存数据,缓存中没有的数据则通过手动构建
new Invocation(invocation.getTarget(), invocation.getMethod(), newArgs).proceed()方式查询数据库。并将查询结果缓存到Redis中。
注意
必须是通过主键对数据查询和更新,非主键或者多个字段查询不支持。按非主键条件更新数据也不支持。
可以先查询出主键id,再通过主键id批量查询数据,更新数据同理。
AI 介绍稿
基于MyBatis拦截器机制实现的二级缓存,使用Redis作为缓存存储。 支持以下功能:
单条记录的主键查询缓存
- 批量查询的mget优化(兼容Redis Cluster)
- 更新操作的缓存失效
- 空值缓存防穿透
- 双删策略保证数据一致性
支持的查询类型:
- 简单主键等值查询:baseMapper.selectById(id)
- LambdaQueryWrapper单主键查询:lambdaQuery().eq(Entity::getId, id)
- 批量主键查询:baseMapper.selectBatchIds(ids)
缓存策略:
- 缓存键格式:{完整类名}:主键值(使用Hash Tag确保Cluster兼容性,避免同名类冲突)
- 正常数据缓存时间:1天(带随机浮动±2.4小时,防止缓存雪崩)
- 空值缓存时间:1分钟(带随机浮动±6秒,防止缓存穿透)
- 浮动过期时间:在基础过期时间上增加±10%的随机时间,避免大量缓存同时过期
Redis Cluster兼容性:
- 使用Hash Tag语法确保同一实体类的key在同一槽位
- 批量操作优先使用multiGet,失败时自动回退到逐个获取
- 完全兼容单机Redis和Redis Cluster部署
- 更新时采用双删策略:操作前删除 -> 执行数据库操作 -> 操作后再删除
相似文章
文章作者 pengxiaochao
上次更新 2025-06-05
许可协议 不允许任何形式转载。