pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
配置类
@EnableConfigurationProperties(CacheProperties.class)
@EnableCaching
@Configuration
public class MyCacheConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 修改默认的序列化器 默认使用JDK序列化 这里修改成json序列化
config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
//重新载入yml的配置。如果不写下面的就不会用到yml的配置。 因为 RedisCacheConfiguration.defaultCacheConfig() 上面的构造了一个新的对象
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;
}
}
配置文件
spring.cache.type=redis
# 以毫秒为单位 1小时 过期时间
spring.cache.redis.time-to-live=3600000
# 配置缓存名的前缀 如果没配置则使用缓存名作为前缀
#spring.cache.redis.key-prefix=CACHE_
# 配置前缀是否生效 默认为ture
#spring.cache.redis.use-key-prefix=false
# 是否缓存空值 默认为true 可以防止缓存穿透
spring.cache.redis.cache-null-values=true
使用:设置缓存, get方法使用
//在方法上贴上Cacheable标签就可以使返回值存储到redis中. 下次获取的时候就会直接从redis中获取.
@Cacheable(value = {"category"}, key = "#root.method.name", sync = true)
@Override
public List<CategoryEntity> getLeve1Categorys() {
System.out.println("CategoryServiceImpl.getLeve1Categorys (获取一级分类)调用了");
List<CategoryEntity> categoryEntityList = baseMapper.selectList(new QueryWrapper<CategoryEntity>().eq("parent_cid", 0));
return categoryEntityList;
}
value = {"category"} :表示缓存的分区
key= "#root.method.name": 表示使用方法名字作为缓存的key
sync = true : 表示在get获取缓存的时候使用加锁的方式获取, 可以在一定程度上预防缓存击穿问题 默认为flase
使用: 清除缓存, update方法使用
/**
* 级联更新所有关联的数据
*
* @param category
*/
//同时操作多个缓存标签时使用Caching
// @Caching(evict = {
// @CacheEvict(value = "category", key = "'getLeve1Categorys'"),
// @CacheEvict(value = "category", key = "'getCatalogJson'")
// })
// allEntries = true 删除category 分区的所有缓存 批量清除
@CacheEvict(value = {"category"}, allEntries = true)
@Transactional
@Override
public void updateCascade(CategoryEntity category) {
this.updateById(category);
// 更新关联表
categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
}
value = {"category"} 指定清除的分区
key = "'getCatalogJson'" 指定清除的名字 对应 @Cacheable里的key = "#root.method.name"
总结:
先从缓存中获取数据 如果没有 就执行方法 然后吧返回值放到缓存中 下次再进来时就不走方法了, 直接从缓存中获取数据
网友评论