一、导入坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
二、写配置
1、在启动类上添加开启缓存注解@EnableCaching
2、 可以往application.properties配置文件中添加以下配置
①、设置使用什么作为缓存
spring.cache.type=redis
②、设置过期时间
#设置过期时间
spring.cache.redis.time-to-live=360000
③、设置缓存前缀
#设置缓存前缀 一旦设置了前缀,那么将不启用缓存的名字
spring.cache.redis.key-prefix=CACHE_
#开启缓存前缀,如果使用缓存前缀,那么缓存的key名字就会加上前缀
spring.cache.redis.use-key-prefix=true
例如以下代码
@Cacheable(value = {"category"}, key = "#root.method.name", sync = true)
@Override
public List<CategoryEntity> getLevel1Categorys() {
System.out.println("查询了数据库");
return baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
// 测试能否缓存null值
// return null;
}
如果没有设置缓存前缀时,redis中的数据:会使用value中的值作为缓存名字
如果设置了缓存前缀,但是不开启缓存前缀:
设置了缓存前缀并且开启
④、设置缓存空值,防止缓存穿透
#缓存空值
spring.cache.redis.cache-null-values=true
三、自定义缓存配置
@EnableConfigurationProperties(CacheProperties.class)
@EnableCaching
@Configuration
public class MyCacheConfig {
/**
* 配置文件中 TTL设置没用上
*
* 原来:
* @ConfigurationProperties(prefix = "spring.cache")
* public class CacheProperties
*
* 现在要让这个配置文件生效 : @EnableConfigurationProperties(CacheProperties.class)
*
*/
@Bean
RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 设置kv的序列化机制
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
CacheProperties.Redis redisproperties = cacheProperties.getRedis();
// 设置配置
if(redisproperties.getTimeToLive() != null){
config = config.entryTtl(redisproperties.getTimeToLive());
}
if(redisproperties.getKeyPrefix() != null){
config = config.prefixKeysWith(redisproperties.getKeyPrefix());
}
if(!redisproperties.isCacheNullValues()){
config = config.disableCachingNullValues();
}
if(!redisproperties.isUseKeyPrefix()){
config = config.disableKeyPrefix();
}
return config;
}
}
四、缓存
1、添加缓存(查询数据时)(sync=true : 加锁)
@Cacheable(value = {"category"}, key = "#root.method.name", sync = true)
@Override
public List<CategoryEntity> getLevel1Categorys() {
System.out.println("查询了数据库");
return baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
// 测试能否缓存null值
// return null;
}
2、修改缓存(失效模式(更改数据后清除缓存))
@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'")
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}
3、修改缓存(失效模式,清空多个缓存)
@Caching(evict = {
@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'"),
@CacheEvict(value = {"category"}, key = "'getCatelogJson'")
})
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}
4、修改缓存(失效模式,删除某一个分区下的所有数据“allEntries = true”)
@CacheEvict(value = {"category"}, allEntries = true)
@Override
public List<CategoryEntity> getLevel1Categorys() {
System.out.println("查询了数据库");
return baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
// 测试能否缓存null值
// return null;
}
三、注解介绍
默认行为:
1、 key自动生成 默认名字 : 缓存的名字::simplekey【】(自主生成的key)
2、缓存的value,默认使用jdk的序列化,将序列化后的内容存到redis中
3、默认的过期时间是永不过期
//用在类上
@CacheConfig(cacheNames = "bank") 用在类上,方法中则可以省略cacheNames 配置
// 用在方法上
@Cacheable: 先判断有没有缓存,有就取缓存,否则查库后再存入缓存,一般用在get 方法上(不支持设置缓存时间)
@CachePut: 操作后结果存入缓存 ,一般用在update上
@CacheEvict: 清除缓存 ,一般用在delete
@Caching 多个Cache组合使用
@Caching(
put = {
@CachePut(value = "bank",key="#bank.bankId"),
@CachePut(value = "bank",key="#bank.bankNo")
}
)
public BankVO save(){}
自定义缓存注解(@Caching组合,会让方法上的注解显得整个代码比较乱)
@Caching(
put = {
@CachePut(value = "bank",key="#bank.bankId"),
@CachePut(value = "bank",key="#bank.bankNo")
}
)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}
value/cacheNames 缓存的名字,必须指定至少一个, 也可以放在CacheConfig()中
key 缓存的key,可以为空,如果指定要按照SpEl表达式编写,如果不指定,则按照所有参数进行组合
condition 缓存的条件,可以为空,使用SpEL编写,返回true、false,只有为true才进行缓存
allEntries 是否清空所有缓存内容,默认为false,如果指定为true,则方法调用后立即清空所有缓存
beforeInvocation 是否在方法执行前就清空,默认为false(如果抛了异常则不会清空缓存),如果指定为true,则在方法还没有执行的时候就清空缓存