Cacheable注解
标记在⼀个⽅法上,也可以标记在⼀个类上缓存标注对象的返回结果,
标注在⽅法上缓存该⽅法的返回值,标注在类上缓存该类所有的⽅法返回值
一般标注在方法上。
@Cacheable(value = {"product"},key = "#root.methodName",cacheManager = "cacheManager1Day") // 放在service层的实现类的某个方法上
// value 缓存名称
// key 缓存的key规则,可以⽤springEL表达式,默认是⽅法参数组合
// 第三个参数对应配置里面的方法
加上缓存注释后,如果第二次查询的时候,会先在缓存中查找,如果数据存在就不会直接取数据库中查找,而是直接利用缓存中的数据
缓存一般需要配置对应的过期时间:
修改redis缓存序列化器和配置manager过期时间
redis: time-to-live: 10 // 在配置文件中配置
也可以在配置类中configuration配置
//配置缓存过期时间,这部分都是官方模板,只需要修改时间
@Bean
@Primary // 缓存一小时 @Primary 是指定默认的,如果在cache里面没有指定就采用这个默认的情况
public RedisCacheManager cacheManager1Hour(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = instanceConfig(3600L); // 配置的过期时间是一小时,ttl单位是秒
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();
}
@Bean // 缓存一天
public RedisCacheManager cacheManager1Day(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = instanceConfig(3600 * 24L);
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();
}
private RedisCacheConfiguration instanceConfig(Long ttl) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
// 去掉各种@JsonSerialize注解的解析
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
// 只针对⾮空的值进⾏序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 将类型序列化到属性json字符串中
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 指定了缓存的单位是秒 ofSeconds 禁止缓存空值 disableCachingNullValues
return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl)).disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
/**
* 自定义缓存key的规则
* @return
*/
@Bean
public KeyGenerator springCacheDefaultKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
return o.getClass().getSimpleName() + "_"
+ method.getName() + "_"
+ StringUtils.arrayToDelimitedString(objects, "_");
}
};
}
自定义缓存的key的规则后,在缓存直接中,参数key'的值直接设置为这个配置的方法的名称
@Cacheable(value = {"product"},keyGenerator ="springCacheCustomKeyGenerator", cacheManager="cacheManager1Minute")
SpringCache框架常⽤注解CachePut
根据⽅法的请求参数对其结果进⾏缓存,每次都会触发真实⽅法的调⽤;
这个注解返回的必须是对象;
@CachePut(value = "product",key = "...",cacheManager = "cacheManager1Day")
// 返回的必须是对象,将这个对象写入到缓存中
public ProductDao updatetest(ProductDao productDao){
productMapper.updateById(productDao);
return productDao;
}
SpringCache框架常⽤注解CacheEvict
从缓存中移除相应数据, 触发缓存删除的操作,主要用于delete方法中
value 缓存名称,可以有多个
key 缓存的key规则,可以⽤springEL表达式,默认是⽅法参数组合
beforeInvocation = false:缓存的清除是否在⽅法之前执⾏ ,默认代表缓存清除操作是在⽅法执⾏之后执⾏;如果出现异常缓存就不会清除
beforeInvocation = true:代表清除缓存操作是在⽅法运⾏之前执⾏,⽆论⽅法是否出现异常,缓存都清除
@Override
@CacheEvict(value = {"product"},key = "#root.args[0]")
public int delById(int id) {
return productMapper.deleteById(id);
}
SpringCache框架多注解组合Caching
组合多个Cache注解使⽤允许在同⼀⽅法上使⽤多个嵌套的@Cacheable、@CachePut和@CacheEvict注释
@Caching(
cacheable = {
@Cacheable(value ="product",keyGenerator = "xdclassKeyGenerator")},
put = {
@CachePut(value ="product",key = "#id"),
@CachePut(value ="product",key = "'stock:'+#id")}
)
当某个方法调用之后可能触发多不同的结果,因此定义多个不同的注解,不同的key
缓存中常见题目
@Cacheable(value = {"product"},key ="#root.args[0]",
cacheManager ="customCacheManager", sync=true)