SpringCache缓存框架
  Spring Cache就是⼀个这个框架。它利⽤了AOP,实现了基于注解的缓存功能,Spring Cache也提供了很多默认的配置,业务代码不⽤关⼼底层是使⽤了什么缓存框架,只需要简单地加⼀个注解,就能实现缓存功能,⽽且SpringBoot项⽬默认集成了Spring Cache。Spring Cache有⼏个常⽤注解,分别为@Cacheable、@CachePut、@CacheEvict、@Caching、 @CacheConfig。除了最后⼀个CacheConfig外,其余四个都可以⽤在类上或者⽅法级别上;
注意:
启动类添加利⽤注解 @EnableCaching 开启SpringCache缓存;
SpringCache利⽤的AOP原理,同类之间调⽤不⽣效;
springboot aop我使⽤的SpringBoot项⽬2.0.2.RELEASE版本,使⽤SpringCache需要能连接上redis,只需要yml⽂件配置上redis的ip和端⼝SpringCache⾃⼰会去连接,如果没配置缓存类型默认是redis不同版本可能不同
spring:
cache:
type: redis #缓存策略redis
redis:
time-to-live:10000 #缓存过期时间,不配置永久有效
redis:
#redis的IP
host:127.0.0.1
#redis的端⼝
port:6379
#redis的数据库默认0号库,默认配置有16个库
database:0
#超时时间
timeout:1800000
除yml⽂件外当然你也可以通过
@Autowired
private CacheManager cacheManager;
来配置springCahe的缓存规则
@Cacheable 注解
标记在⼀个⽅法上,也可以标记在⼀个类上;
缓存标注对象的返回结果,标注在⽅法上缓存该⽅法的返回值,标注在类上缓存该类所有的⽅法返回值;
value缓存名称,可以有多个;
key缓存的key规则,可以⽤springEL表达式,默认是⽅法参数组合;
condition缓存条件,使⽤springEL编写,返回true才缓存;
/**
* 分页缓存对应缓存  priduct_page::getPage_1_10
* @return
*/
@Override
@Cacheable(value ={"product_page"},key ="#hodName+'_'+#page+'_'+#size")
public List<String>getPage(Integer page, Integer size){
System.out.println("++++++++++进⼊查询⽅法+++++++++");
ArrayList<String> arr =new ArrayList<>();
arr.add("aa");
return arr;
}
/**
* 分页缓存对应缓存  priduct_page::getPageV2_1_10
* QueryPageReqDTO ⾥⾯的属性是 Integer类型的page和size
*/
@Override
@Cacheable(value ={"product_page"},key ="#hodName+'_'+#req.page+'_'+#req.size")
public List<String>getPageV2(QueryPageReqDTO req){
System.out.println("++++++++++进⼊查询⽅法V2+++++++++");
ArrayList<String> arr =new ArrayList<>();
arr.add("aa");
return arr;
}
/**
* 分页缓存对应缓存  priduct_page::1
* @return
*/
@Override
@Cacheable(value ={"product_page"},key ="#root.args[0]")
public List<String>getPageV3(Integer page, Integer size){
System.out.println("++++++++++进⼊查询⽅法V2+++++++++");
ArrayList<String> arr =new ArrayList<>();
arr.add("aa");
return arr;
}
redis数据库会缓存
127.0.0.1:6379> keys *
1)"product_page::getPage_1_10"
127.0.0.1:6379>
127.0.0.1:6379> ttl product_page::getPage_1_10
(integer)8
127.0.0.1:6379>
@CachePut注解
根据请求参数对其结果进⾏缓存,与@Cacheable不同每次都会进⼊⽅法执⾏⽅法⾥⾯的逻辑,所以经常会⽤在update⽅法上⾯,如更新数据后同步缓存的操作上⾯;
注意:缓存的是你的返回值,所以不要写更新数据库时int类型的受影响⾏数,要对应某条数据的DTO对象
@CachePut(value ={"product_page"},key ="#root.args[0]")
public TestDTO  updateById(@RequestParam("id") Integer id){
System.out.println("++++++++++进⼊修改⽅法+++++++++");
System.out.println("++++++++++更新数据库+++++++++");
return更新后数据库的最新数据,达到同步缓存的⽬的;
}
@CacheEvict注解
经常⽤来清除缓存,⽐如删掉数据库的某条数据,也会将其对应的缓存进⾏删除,它有个beforeInvoc
ation参数默认为false,在⽅法执⾏完成之后再执⾏,如果出现异常那么不会删除缓存,true就是先删除缓存再执⾏⽅法,⽆论⽅法是否发⽣异常都会删除缓存;
@CacheEvict(value ={"product_page"},key ="#root.args[0]",beforeInvocation =true)
public Boolean  deleteById(@RequestParam("id") Integer id){
System.out.println("++++++++++进⼊删除⽅法+++++++++");
return true;
}
@Caching注解
它是⼀个组合注解,也就是在复杂场景下同时可对数据进⾏缓存,同时进⾏修改和删除,Cahing⽀持
@Cacheable,@Cacheput,@CacheEvict这三个注解进⾏随意组合,以达到同时对⼀个或者多个缓存同时操作的⽬的;
@Caching(
cacheable ={
@Cacheable(value ={"product_page"},key ="#root.args[0]")
},
put ={
@CachePut(value ={"product_page"},key ="'ABC_'+#root.args[0]"),
@CachePut(value ={"product_page"},key ="#root.args[0]")
},
evict ={
@CacheEvict(value ={"product_page"},key ="#root.args[0]",beforeInvocation =true)
}
)
public Test selectOrUpdateOrDelById(@RequestParam("id") Integer id){
System.out.println("++++++++++进⼊⽅法V5+++++++++");
return组合注解;
}
@CacheConfig注解
这个注解只能作⽤在类上⾯,它是个公共的配置注解,如@Cacheale,@Cacheput,@CacheEvict他们都有value属性,@CacheConfig 就是可以取代这个属性;
@CacheConfig(cacheNames={"BBQ","ABC"})
public class TestController {
@Cacheable(key ="#root.args[0]")
public List<String>cacheableTest3(@RequestParam("page") Integer page,@RequestParam("size") Integer size){
System.out.println("++++++++++进⼊查询⽅法+++++++++");
ArrayList<String> arr =new ArrayList<>();
arr.add("ee");
arr.add("ff");
return arr;
}
}
那么对应的缓存key就是
127.0.0.1:6379> keys *
2)"ABC::1"
3)"BBQ::1"