原理:在 SpringBoot 的 Cache 中,会默认使用 SimpleCacheManager
, 生成一个 KeyGenerator()
,将数据保存在 ConcurrentMap<Object,
Object>
中
也就是重写一个 MyCacheConfig
类,来覆盖 @EnableCaching
默认的方法
@Configuration
public class MyCacheConfig {
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
return method.getName() + "[" + Arrays.asList(params).toString() + "]";
}
};
}
}
在这里打下断点来测试
访问来到了自定义的配置的 cache,说明配置成功
## @Cacheable
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable 作用和配置方法
|
参数 | 解释 | example |
---|---|---|
value | 缓存的名称 在 spring 配置文件中定义,必须指定至少一个 | 例如 @Cacheable(value=”mycache”)@Cacheable(value={”cache1”,”cache2”} |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | @Cacheable(value=”testcache”,key=”#userName”) |
condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
// value指的是路由emp,
@Cacheable(value = {"emp"} ,keyGenerator = "myKeyGenerator", condition = "#a0>1",unless = "#a0==2")
public Employee getEmp(Integer id) {
System.out.println("查询" + id + "号员工");
Employee emp = employeeMapper.getEmpById(id);
return emp;
}
condition = "#a0>1":第一个参数的值 > 1 的时候才进行缓存
unless = "#a0==2": 如果第一个参数的值是 2,结果不缓存;
## @CachePut
@CachePut:既调用方法,又更新缓存数据;同步更新缓存 修改了数据库的某个数据,同时更新缓存;
使用 CachePut 注解,该方法每次都会执行,会清除对应的 key 值得缓存 (或者更新),分为以下两种情况:
如果返回值 null,下次进行该 key 值查询时,还会查一次数据库,此时相当于 @CacheEvict 注解; 如果返回值不为 null,此时会进行该 key 值缓存的更新,更新缓存值为返回的数据;
@CachePut 注释,这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中,实现缓存与数据库的同步更新。
@CachePut(value = "emp",key = "#result.id")
public Employee updateEmp(Employee employee) {
System.out.println("updateEmp:" + employee);
employeeMapper.updateEmp(employee);
return employee;
}
* 1、查询1号员工;查到的结果会放在缓存中;
* key:1 value:lastName:张三
* 2、以后查询还是之前的结果
* 3、更新1号员工;【lastName:zhangsan;gender:0】
* 将方法的返回值也放进缓存了;
* key:传入的employee对象 值:返回的employee对象;
* 4、查询1号员工?
* 应该是更新后的员工;
* key = "#employee.id":使用传入的参数的员工id;
* key = "#result.id":使用返回后的id
* @Cacheable的key是不能用#result 为什么是没更新前的?【1号员工没有在缓存中更新】
现在将 1 号数据更改
再查就是 maoli 了
## @CacheEvict
@CacheEvict 缓存清除 key:指定要清除的数据
@CacheEvict(value = "emp", key = "#id"/*,beforeInvocation = true*/)
public void deleteEmp(Integer id) {
System.out.println("deleteEmp:" + id);
employeeMapper.deleteEmpById(id);
//int i = 10 / 0;
}
查询 1 号
删除 1 号员工
查不到
原创声明:本文是毛利原创文章