环境:
redis跟缓存依赖是必须的
<dependency>
<!-- 缓存依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mybatis依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- msql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 数据库相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- web项目依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
这边贴出相关配置,空格啥的自己对对好
spring:
redis:
host: 127.0.0.1
database: 0
password:
port: 6379
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
timeout: 5000 # 连接超时时间(毫秒)
## Cache部分
cache:
cache-names: mysqls #缓存的名称集合,多个采用逗号分割
type: redis #缓存的类型,官方提供了很多,这里我们填写redis
redis:
cache-null-values: false #是否缓存null数据,默认是false
time-to-live: 6000000 #redis中缓存超时的时间,默认60000ms
# use-key-prefix: true #缓存数据key是否使用前缀,默认是true
# key-prefix: wz- #缓存数据key的前缀,在上面的配置为true时有效
use-key-prefix这个属性不要,必须注释掉,false没有用,不然方法的Cacheable注解中value无效
启动类添加注解
@EnableCaching
缓存数据的方法添加注解
@Cacheable(value = "selectList",key = "#tableName+' '+#sqlLimit")
public List selectList(String tableName, String sqlLimit) {
return baseMapper.selectList(" * ",tableName," and "+sqlLimit);
}
这里key策略我这使用全部参数(这个随意,根据项目来)
删除方法缓存注解
@Caching(evict={@CacheEvict(value = "selectString",key = "#tableName")
,@CacheEvict(value = "selectOne",key = "#tableName")
,@CacheEvict(value = "selectListJson",key = "#tableName")
,@CacheEvict(value = "selectList",key = "#tableName")
,@CacheEvict(value = "selectPageList",key = "#tableName")
})
public Integer delete(String tableName, String[] params) {
return baseMapper.delete(tableName, params);
}
我这配置了多个方法的删除(实际根据项目来)
我这缓存key是方法名称【CacheEvict的value值】+表名称+参数
上面部分都是常用的,百度都搜索的到。
到这里调用查询方法就能将查询数据缓存到redis中了。
但是CacheEvict删除缓存只能key-value删除,有时候业务需要根据某些属性删除多个key,比如表数据变更,需要删除表相关全部缓存key。
下面是重点
我这里需要删除表相关的缓存【不论查询参数缓存了多少个key】
原理很简单:利用spring aop切面对注解进行切片拓展,不会影响原来的注解方式等
利用spring aop切面后可以获取注解的CacheEvict的value值,key值等等,进行组装成通用key,然后用StringRedisTemplate类(RedisTemplate也可以)进行删除
直接上代码
@Component
@Aspect
public class Caching_expend {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
//这边是我自己封装的工具类,可以注入StringRedisTemplate实现,效果一样
RedisUtils RedisUtils;
//截获标有@Caching的方法
//我配置Caching,如果只有单个@CacheEvict这个,下面的类名称Caching改成CacheEvict即可【在同一个包】
@Pointcut(value = "(execution(* *.*(..)) && @annotation(org.springframework.cache.annotation.Caching))")
private void pointcut() {
}
/**
* 功能描述: 切面在截获方法返回值之后
*
* @return void
* @throws
* @author wz
* @date 2020/01/02 16:55
* @params [joinPoint]
*/
@AfterReturning(value = "pointcut()")
private void process(JoinPoint joinPoint) {
//获取被代理的类
Object target = joinPoint.getTarget();
//获取切入方法的数据
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取切入方法
Method method = signature.getMethod();
Object[] args=joinPoint.getArgs();
//获得注解
//单个@CacheEvict这个,下面的类名称Caching改成CacheEvict即可
Caching Caching = method.getAnnotation(Caching.class);
if (Caching != null) {
//单个@CacheEvict这个for循环就不需要了
for(CacheEvict CacheEvict:Caching.evict()){
String[] value = CacheEvict.value();
String keys = CacheEvict.key();
if (!"".equals(value)&&value.length>0) {
//这边可以根据自己需求进行自定义的删除
String key=value[0]+"::"+args[0].toString()+"*";
Set<String> deletekeys = RedisUtils.keys(key);
RedisUtils.delete(deletekeys);
}
}
}
}
}
上面定义后可以断点调试合适自己项目的模糊key。
测试类啥的自己写哦
本文不适合小白哦,如果帮助到你欢迎点个赞。
不明白底下留言。看到会回复