springboot中在⽅法上使⽤@Cacheable注解实现redis缓存
简介
平时⼤家使⽤redis⼀般都是直接存储key,value.
spring全家桶肯定帮⼤家想到了这⼀点.可以让⼤家⽅便的使⽤注解操作redis节省代码量.
把总结放前⾯:
总共有三种⽅式,底层利⽤了spring的aop,并且⽅法返回的对象⼀定要实现序列化
@Cacheable:注解于⽅法上,第⼀次会把后⾯的cacheNames+key 拼接为key,把返回值序列化后作为value set到redis中去.后⾯再⼀次访问相同的key的时候就直接从redis中取值了,不会再访问这个⽅法
@Override
@Cacheable(cacheNames ="product",key ="#id")
public ProductInfo findOne(String id){
return productInfoRepository.findById(id).orElse(null);
}
@CachePut:每次都会把⽅法的返回值序列化之后set到redis中去(每次都会执⾏⽅法),即更新这个key对应的值
@Override
@CachePut(cacheNames ="product",key ="#productId")
public ProductInfo onSale(String productId){
ProductInfo productInfo =this.findOne(productId);
if(null== productInfo){
throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
}
ProductStatusEnum().getCode()== Code()){
log.warn("[商品上架处理]-----商品已经是上架状态了,这⾥直接返回原ProductInfo={}",productInfo);
springboot aop}else{
productInfo.setProductStatus(Code());
productInfo =this.save(productInfo);
}
return productInfo;
}
@CacheEvict:这个⽐较好理解,就是从redis中把这个key删除了
@Override
@CacheEvict(cacheNames ="product",key ="#productInfo.productId")
public ProductInfo save(ProductInfo productInfo){
return productInfoRepository.save(productInfo);
}
这⾥的key其实可以不写,⽐如上⾯的@CacheEvict中不写的话就会把参数默认为key,即下⾯的productInfo对象
⼀次驱逐多个redis的key
@Caching(evict={
@CacheEvict(value = Cache.CONSTANT, key ="'"+ CacheKey.SINGLE_ROLE_NAME +"'+#roleId"),
@CacheEvict(value = Cache.CONSTANT, key ="'"+ CacheKey.ROLES_NAME +"'+#roleId"),
@CacheEvict(value = Cache.CONSTANT, key ="'"+ CacheKey.SINGLE_ROLE_NAME +"'+#roleId")
})
public ResponseData remove(@RequestParam Long roleId){
………………
}
⽤cacheManager⼿动put key和value
@Autowired
private CacheManager cacheManager;
...
使⽤注解前现在启动类中加上@EnableCaching注解
这个注解是spring的,在spring-boot-starter-web包中.⼀般使⽤springmvc的都在springboot中引⼊这个依赖了,所以不⽤另外引⼊依赖了.
如果你想单独引⼊这个依赖的话
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
可以加在⽅法上使⽤@Cacheable set value到redis
使⽤@Cacheable后,第⼀次会把后⾯的cacheNames+key 拼接为key,把返回值序列化后作为value set到redis中去.后⾯再⼀次访问相同的key的时候就直接从redis中取值了,不会再访问这个⽅法,也就不会再从数据库中取值了
可以把⽅法中的参数拼到key上,在这个⽅法运⾏完后会把这个⽅法的返回值根据@Cacheable注解中的cacheNames+key拼接后的值为key,set到redis中取,下次再访问这个key的时候直接从redis中取数据,不⽤去mysql查⼀遍了
redis中缓存的key
使⽤condition,对传⼊的参数进⾏,筛选只允许符合条件的请求set到redis中
对于现实的需求,肯定有些时候是异常请求,是不需要缓存到redis中的,这⾥我们也可以使⽤condition加上判断,判断通过的时候才允许缓存到redis
有根据请求筛选,那么⾃然也就有根据⽅法的结果筛选的,根据结果筛选可以使⽤unless
@Cacheable中,unless参数的作⽤是:函数返回值符合表达式条件的,veto(否决)、不缓存
换句话说,函数返回值符合条件的排除掉、只缓存其余不符合条件的
若是想要某种条件下才缓存,那么可以在el表达式中对其他情况取反就⾏了
例如,想要返回结果中productId = 1的,那么可以这样写
@Cacheable(cacheNames = “product111”,key = “#productInfo.productId”, unless =
“!#result.productId.equals(‘1’)”)
把结果中不等于1的排除掉,那么剩下的就是等于1了
这⾥可能有点绕,因为unless⾃动在最外⾯取了个反,所以要双重否定
简单说就是对你想要的结果取反,unless⾃⼰外⾯有取反!!2个取反就还是原先的结果
@CachePut 更新value到redis
@CachePut和@Cacheable的相同点都可以加在⽅法上
不同之处在于@CachePut是每次都会把⽅法的返回值序列化之后set到redis中去(每次都会执⾏⽅法),即更新这个key对应的值,适合⽤于修改值的⽅法
这⾥要注意⼀点参数⾥的key后⾯⽀持spel表达式,可以从下⾯的⽅法中获取参数,然后类型和获取的参数的类型是⼀样的,虽然外⾯的双引号,但是⾥⾯你直接给个数字,它会当成int去处理的,int的话就会有上限2^31 -1
⽐如,下图中key就为String类型的字符串
⽽下图中key的值就是int类型的
@CacheEvict 从redis中删除 key
这个也⽐较好理解,就是从redis中把这个key删除了
这⾥的key其实可以不写,不写的话就会把参数默认为key,即下⾯的productInfo对象
使⽤@CacheConfig注解可以让多个⽅法使⽤统⼀的cacheNames
如果在同⼀个类中,要使⽤redis缓存的每个⽅法中都要写cacheNames是不是觉得很⿇烦,可以使⽤@CacheConfig(cacheNames =“product”),为下⾯的注解默认使⽤上⾯这个CacheConfig中定义的cacheNames
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论