springboot自定义cache
原理:在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;
}
-
cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
-
condition:指定符合条件的情况下才缓存;
-
condition = “#id>0”
condition = “#a0>1”:第一个参数的值>1的时候才进行缓存
- unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断
- unless = “#result == null”`
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:缓存清除 key:指定要清除的数据
-
allEntries = true:指定清除这个缓存中所有的数据
-
beforeInvocation = false:缓存的清除是否在方法之前执行
-
默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除
-
beforeInvocation = true:
-
代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
@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号员工
查不到