SpringCache缓存笔记

Spring专门对缓存的一个抽象层

1. 引入依赖

spring-boot-starter-cache

spring-boot-starter-data-redis

2. 写配置

在application中配置使用的那个缓存

spring.cache.type=redis

2.1 缓存的名字

可以不配置,会自动生成,

如果配置,会禁用实时的创建这个名字的功能,

​ 以后只会使用你配置的名字

3. 测试使用缓存

//触发将数据保存到缓存的操作
@Cacheable: Triggers cache population.
    
//触发将数据从缓存删除的操作--redis失效模式进行缓存更新
@CacheEvict: Triggers cache eviction.
    
//不影响方法执行更新缓存--redis双写模式进行缓存更新
@CachePut: Updates the cache without interfering with the method execution.
    
//组合以上操作
@Caching: Regroups multiple cache operations to be applied on a method.
    
//在类级别共享缓存的相同配置
@CacheConfig: Shares some common cache-related settings at class-level.

3.1 使用缓存

  1. 开启缓存功能

    ​ @EnableCaching 注解使用在主启动类上

  2. 只需要使用注解就可以操作缓存–默认设置

    • @Cacheable //代表当前的结果需要缓存-位置方法上

      如果缓存中有,方法不调用,如果没有,就会调用方法,将方法的结果放入缓存

    • 每一个需要缓存的数据,我们都来指定要放到哪个名字的缓存中

      @Cacheable(value=“item”)

3.2 默认行为

  1. 如果缓存中有,方法不调用
  2. redis中的key默认自动生成
  3. redis缓存中的值,默认使用jdk序列化机制,将序列化后的数据存到redis中
  4. 默认ttl时间 -1 永不过期

3.3 *自定义行为

  1. 指定生成缓存需要的key, 使用注解的key属性,接收一个SpEL,所以不能直接用key的名字,需要加上单引号
//指定缓存分区,和缓存的key名称
@Cacheable(value="item",key="'selectItem'")
@GetMapping("/getItem")
public R selectItem(){
    
}
名称地点描述例子
methodNameroot被调用方法的名称#root.methodName
methodroot被调用的方法#root.method.name
targetroot被调用的目标对象#root.target
targetClassroot被调用目标的类#root.targetClass
argsroot用于调用目标的参数(作为数组)#root.args[0]
cachesroot运行当前方法的缓存集合#root.caches[0].name
参数名称评价背景任何方法参数的名称。如果名称不可用(可能是由于没有调试信息),则参数名称也可在代表参数索引的#a<#arg> where下#arg(从 开始0)。#ibanor #a0(您也可以使用#p0or#p<#arg>符号作为别名)。
result评价背景方法调用的结果(要缓存的值)。仅在unless 表达式、cache put表达式(用于计算key)或cache evict 表达式(何时beforeInvocationfalse)中可用。对于支持的包装器(例如 Optional),#result指的是实际对象,而不是包装器。#result
  1. 指定缓存中数据的存活时间

在application配置文件中设置过期时间

//单位毫秒--10000毫秒是10秒
spring.cache.redis.time-to-live=10000
  1. 指定redis中数据的value的类型为json格式

CacheAutoConfiguration缓存的自动配置类,

自动配置 会导入redis的缓存配置类RedisCacheConfiguration,

redis缓存配置类 会自动配置redis的缓存管理器RedisCacheManager

初始化所有的缓存

每个缓存觉得使用什么配置,如果RedisCacheConfiguration有就用, 没有就用自己的

如果想改缓存的配置, 就需要给容器汇总放一个RedisCacheConfiguration

@EnableCaching
@Configuration
public class MyRedisCacheConfig {

    @Bean
    RedisCacheConfiguration redisCacheConfiguration(){
        //先使用默认配置,我们再进行修改
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        //设置缓存过期时间,单位分钟
        config = config.entryTtl(Duration.ofMinutes(10));
        //使用一个String类型的序列化key名称
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        //使用一个json类型的序列化value值Generic代表可以转换为对象的方式
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
        return config;
    }
}

删除缓存-更新缓存-失效模式

@CacheEvict(value="item",key="'selectItem'")//缓存更新-失效模式
//删除缓存,缓存的分区和redis中key的名字都需要指定,之前存入的是那种现在就是那种
public R updateItem(String id){
	
}

组合操作

如果,更新缓存需要删除两个缓存内容,一个页面的一个后台的,则需要使用@Caching组合操作,删除两个缓存

  @Caching(evict = {
            //删除两个缓存的操作
            @CacheEvict(value = "item",key = "'cacheItem'"),
            @CacheEvict(value = "item",key = "'getCacheItem'"),
    })
//或者
//删除item分区里面的所有数据
//同一种类型的数据,可以存同一分区, 当我们修改了这个类型的数据,那么我们就可以直接删除这个类型的所有
//以后我们不要指定前缀,就用他的分区名称作为前缀--默认不写即可
@CacheEvict(value = "item",allEntries = true)

缓存雪崩,这里就不用设置随机的过期时间,

因为你加入缓存的时间不一致,直接导致,你的过期时间是不同的

Spring cache 解决缓存问题

写模式-保证缓存与数据库一致

  1. 读多: 读写加锁
  2. 引入中间件Canal,感知到mysql的更新,去更新缓存
  3. 读多写多, 直接去数据库,不通过缓存

读模式

  1. 缓存穿透: 查询一个null的数据, 解决: 缓存空值,cache解决,配置文件配置

     cache:
        redis:
          cache-null-values: true  # 缓存空值
    
  2. 缓存击穿: 大量查询一个将要过期的值, 解决:加锁访问数据库,

    //cacheable注解可以使用本地锁,一般来说,本地锁够用了
    @Cacheable(value="item",key="'selectItem'",sync=true)
    
  3. 缓存雪崩: 大量缓存失效, 解决: 加上随机过期时间, 在cache中只需要添加过期时间即可, 你加入的缓存时间不同, 那么,你失效的时间也会不同

总结

  1. 常规数据: 直接使用springCache就可以满足了
  2. 特殊数据: 特殊设计, 自己写如何存入缓存,如何失效, 如何保证数据一致性, 分布式锁,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值