1.快速体验缓存
1)开启基于注解的缓存 @EnableCaching
2) 开启缓存注解即可
@Cacheable
@CacheEvict
@CachePut
2. @Cacheable初体验
CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;
几个属性:
cacheNames/value: 指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的方式;可以指定多个缓存;
key :缓存数据使用的key可以用它来指定;默认是使用方法参数的值 方法的返回值
编写SpEL #id;参数id的值 #a0 #p0 #root.args[0]
keyGenerator: key的生成器;可以自己指定key的生成器的组件id
key/keyGenerator ; 二选一使用
cacheManager: 指定缓存管理器;或者cacheResolver指定获取解析器
condition: 指定符合条件的情况下才缓存;
condition = "#a0>1":第一个参数的值>1的时候才进行缓存
unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;
unless="#result==null"
sync: 是否使用异步模式
3.运行流程:
@Cacheable:
1) 方法运行之前,先去查询Cache(缓存组件) ,按照cacheNames指定的名字获取;
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2)去Cache中查找缓存的内容,使用一个key ,默认就是方法的参数
key是按照某种策略生成的,默认是使用keyGenerator生成的, 默认使用SimpleKeyGenerator生成key
SimpleKeyGenerator生成key的默认策略:
如果没有参数: key=new SimpleKey();
如果有一个参数: key=参数的值
如果有多个参数:key=new SimpleKey(params)
3)没有查到缓存就调用目标方法;
4)将目标方法返回的结果,放进缓存中
@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存
如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据;
核心: 1)使用CacheManager【ConcurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件
2)key使用keyGenerator生成的, 默认使用SimpleKeyGenerator生成key
4.@CachePut:既调用方法,又更新缓存数据;同步更新缓存;
修改了数据库的某个数据,同时更新缓存;
运行时机:
1、先调用目标方法
2、将目标方法的结果缓存起来
3、@Cacheable的key是不能用#result,因为它的运行时机是调用方法之前就要用key去查缓存
5.@CacheEvict :缓存清除
key: 指定要清除的数据
allEntries = true : 指定清除这个缓存中所有的数据
beforeInvocation = false 缓存的清除是否在方法之前执行,默认是在方法之后执行的
beforeInvocation = true 代表清除缓存是在方法运行之前执行,无论方法是否出现异常,缓存都清除
6. @Caching: 定义复杂的缓存规则
@Caching(
cacheable = {
@Cacheable(value = "emp",key = "#lastName" )
},
put = {
@CachePut(value = "emp",key = "#result.id"),
@CachePut(value = "emp",key = "#result.email")
}
)
7.@CacheConfig(cacheNames="emp") //抽取缓存的公共配置
8. 整合redis :使用docker;
1) 引入redis的starter
2) 配置redis
3) 引入redis的starter,容器中保存的是RedisCacheManager,它帮我们创建RedisCache 来作为缓存组件,RedisCache通过操作redis来缓存数据
4)利用StringRedisTemplate;操作k-v都是字符串的 或者RedisTemplate操作k-v都是对象的来操作redis的五大数据类型
5) 默认保存数据 k-v 都是Object;利用序列化保存,默认创建的 RedisCacheManager 操作redis的时候使用的是 RedisTemplate<Object,Object>,它默认使用jdk的序列化机制
6)可以通过自定义RedisTemplate来改变默认的序列化机制,譬如,采用json