SpringCache

一、整合SpringCache

1、导入依赖
<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>
2.配置
spring:
  cache:
    type: redis
3.开启测试及注解

image-20210408012913075

1.开启缓存

image-20210408013028167

2.添加注解

简单实例

    //每一个需要缓存的数据我们都来指定放在那个名字的缓存
    @Cacheable("category") //代表当前方法结果需要缓存,如果缓存中有,方法不调用。如果方法没有缓存调用
    @Override
    public List<CategoryEntity> getLevel1Categories() {
        List<CategoryEntity> categoryEntityList = this.list(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
        return categoryEntityList;
    }

注意@Cacheable为org.springframework.cache.annotation.Cacheable

不是springfox.documentation.annotations.Cacheable

3.默认行为
  • 如果缓存中有,方法不用调用
  • key默认自动生成:缓存的名字::SimpleKey []
  • 缓存默认的值默认用jdk序列化,讲序列化后的值存入redis
  • 默认ttl时间-1
4.自定义
  1. 指定生成缓存使用的key

    @Cacheable(value = {"category"}, key = "'level1'") 
    
  2. 指定缓存的数据的存活时间

    spring:
      cache:
        type: redis
        redis:
          time-to-live: 36000000
    

​ 3.将数据保存为json形式

@EnableConfigurationProperties(CacheProperties.class)//自动注入配置类,可不用@Autowire,在形参中直接写即可
@EnableCaching
@Configuration
public class MyCacheConfig {

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
        //获取默认配置类
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //配置key编码格式
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()));
        //配置value编码格式
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
        //添加配置内后,会覆盖yaml中配置的一些属性,如此处的过期时间,故要重新获取
        config = config.entryTtl(cacheProperties.getRedis().getTimeToLive());
        return config;
    }

}
三、失效模式
  • 注解 @CacheEvict(value = “category”, allEntries = true)

方法一

@Transactional
@CacheEvict(value = "category", allEntries = true)
@Override
public void updateDetail(CategoryEntity category) {
    this.updateById(category);
    Long catId = category.getCatId();
    String categoryName = category.getName();

    if (categoryName != null && categoryName != "")
    categoryBrandRelationService.updateDeatil(catId,categoryName);
}

方法二

@Caching(evict = {
        @CacheEvict(value = {"category"}, key = "'level1'"),
        @CacheEvict(value = {"category"}, key = "'getCatalogJson'")
})
public void updateDetail(CategoryEntity category) {
    this.updateById(category);
    Long catId = category.getCatId();
    String categoryName = category.getName();

    if (categoryName != null && categoryName != "")
    categoryBrandRelationService.updateDeatil(catId,categoryName);
}
四、Spring-Cache的不足
  1. 读模式

    • 缓存穿透:查询一个null数据 解决无需考虑 空数据可写入缓存

    • 缓存击穿:大量并发查询一个正好过期的数据 解决:加锁sync = true

      @Cacheable(value = {"category"}, key = "'level1'", sync = true)
      
    • 缓存雪崩:大量key同时过期。加上随机时间。加上过期时间

  2. 写模式

    • 读写加锁
    • 引入Canal,感知到Mysql的更新去更新数据库
    • 读多写多,直接去数据库查询就行

y = “‘level1’”, sync = true)
```

  • 缓存雪崩:大量key同时过期。加上随机时间。加上过期时间
  1. 写模式

    • 读写加锁
    • 引入Canal,感知到Mysql的更新去更新数据库
    • 读多写多,直接去数据库查询就行

常规数据(读多写少,及时性,一致性要求不高的数据):完全可以使用Spring-Cache:写模式(只要缓存的数据有过期)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值