前言:
上篇博客【springBoot】springboot2.X 整合spring默认的缓存及其原理(上)主要讲解了缓存的原理以及@cacheable的用法,本篇博客补充一下其它缓存注解的用法
@cacheable 调用方法之前,先看有没有数据
@CachePut 先调用方法,然后将结果进行缓存
1、@CachePut
保证方法被调用,又更新缓存数据(执行完方法后,将方法的返回值放入缓存)
上面解释完,可能有人觉得那么这个注解有什么作用啊,每次都调用方法,也就是意味着每次都要调用数据库,缓存没有起到任何作用,其实它必须要和Cacheable一起组合起来就会发现它的作用了。
@Cacheable 调用方法之前,先看缓存中有没有数据,如果有数据那么就从缓存中获取数据,没有就查询数据库。但是想在有这么一种情形,就是我在后台更新了一条id=1的数据,此时id=1的数据在缓存中还是没有更新的数据。那么在查询id=1这条数据的时候发现缓存有对应的数据,就会从缓存中取,缓存的数据还是之前的数据,没有更新,此时用户获得的数据是不正确的数据,那么@CachePut出来可以完美解决问题。
@CachePut注解可以保证你的更新数据的方法被执行,然后将更新后的结果存储到缓存中,如果缓存中的id相同,那么就会覆盖数据,使得缓存中的数据是最新的数据
1.1例子
@Autowired
public EmployeeMapper employeeMapper;
key="#a0" 表示的意思是第一个参数为key
@Cacheable(cacheNames = {"emp"},key="#a0")
public Employee getEmpById(Integer id){
return this.employeeMapper.getEmpById(id);
}
//key="#result.id"也是可以的,具体为啥,看上篇博客
@CachePut(cacheNames = {"emp"},key="#employee.id")
public Employee updateEmployee(Employee employee){
this.employeeMapper.updateEmp(employee);
return employee;
}
上面两段代码的意思就是对缓存中相同的key进行操作,经过测试方法updateEmployee传入id=1的employee对象后,然后在调用方法getEmpById,传入参数id=1,发现并没有访问数据库,查询出的数据正是方法updateEmployee更新的数据,说明@CachePut生效。
2、@CacheEvicat
缓存清除
和之前一样,可以按照指定的key进行删除,接下来简单介绍下他的其它的两个属性:
allEntries = true:指定清除这个缓存中所有的数据
beforeInvocation = false:缓存的清除是否在方法之前执行
默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
beforeInvocation = true: 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
3、@Caching
定义复杂的缓存规则
从下面的Caching源码中我们看出,@Caching组合了Cacheable、CachePut、CacheEvict三个注解,当有些方法的缓存规则比较复杂的时候我们可以用它。
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
3.1 例子
下面的例子,表示缓存了key=lastname的对象employee,同时更新了缓存中key=id 和key=email的数据,当有些方法是按照id查询数据的时候,就出从缓存中获取下面方法更新的数据
@Caching(
cacheable = {
@Cacheable(value="emp",key = "#lastName")
},
put = {
@CachePut(value="emp",key = "#result.id"),
@CachePut(value="emp",key = "#result.email")
}
)
public Employee getEmpByLastName(String lastName){
return employeeMapper.getEmpByLastName(lastName);
}
4、@CacheConfig
public @interface CacheConfig {
String[] cacheNames() default {};
String keyGenerator() default "";
String cacheManager() default "";
String cacheResolver() default "";
这个注解作用于类上,主要是用来公共配置的,上面的代码中都配置了value=“emp”,我们可以在类上加上注解@CacheConfig
如下:
@CacheConfig(cacheNames=“emp”) //抽取缓存的公共配置
此时我们的其它配置就可以省略了value="emp"如
@Caching(
cacheable = {
@Cacheable(key = "#lastName")
},
put = {
@CachePutkey = "#result.id"),
@CachePut(key = "#result.email")
}
)
public Employee getEmpByLastName(String lastName){
return employeeMapper.getEmpByLastName(lastName);
}
后记
spring默认缓存管理器是currentHashMap,接下来的文章介绍redis方式的缓存,类似@Cacheable @CachePut注解在redis中同样其作用,但是和默认的有啥区别,请看下篇文章 【SpringBoot】springboot整合redis以及原理