前面SpringBoot+mybatis+redis项目示例中虽然实现了整合redis,但是太过繁琐对数据库操作的同时,都需要写相关的redis操作语句。
于是了解到SpringCache的注解,使用注解可以节省很多功夫
一、使用思路
- 查询:将查询出来的数据写入到缓存中,后续查询直接访问缓存
- 插入:新增数据时,同时将数据写入到缓存中
- 更新:不对原有缓存进行更新,而是将缓存删除,等待后面查询数据时,将更新后的数据写入到缓存中
- 删除:删除数据的同时,将数据从缓存中删除
从上面的情况,我们可能会想到一个问题:
单个数据通过查询写入缓存,更新时缓存被删除直到再一次查询时写入,可以保证缓存数据的正确性。
但是如果缓存存放的是一个集合的,不会因为单个数据的操作进行变化。
这个时候,我们可以通过设置缓存的失效时间来保证缓存的正确性,失效后缓存被删除,下一次会重新访问数据库然后重新写入到缓存中
二、引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
三、配置文件
spring:
redis:
host: 127.0.0.1
port: 6379
pool:
max-active: 100
max-idle: 10
max-wait: 100000
timeout: 0
四、配置类
这里主要为配置两个功能:
- 管理缓存的失效时间;
- key的自动生成
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
/**
* 缓存管理
* @param redisConnectionFactory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.getRedisCacheConfigurationWithTtl(30*60),//默认缓存失效策略,默认失效时间为30分钟
this.getRedisCacheConfigurationMap()//指定策略
);
}
/**
* 配置缓存失效时间
* @param seconds
* @return
*/
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer)
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
/**
* 根据key指定对应的缓存策略
* @return
*/
private Map<String,RedisCacheConfiguration> getRedisCacheConfigurationMap(){
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
//对查询所有数据的缓存失效时间设置为10秒
redisCacheConfigurationMap.put("selectIndexList",this.getRedisCacheConfigurationWithTtl(10));
return redisCacheConfigurationMap;
}
/**
* key自动生成类
* @return
*/
@Bean("myKeyGenerator")
public KeyGenerator KeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
System.out.println(Arrays.asList(params));
List<String> paramList = Arrays.asList(params).stream().map(p->{
return p.toString();
}).collect(Collectors.toList());
return target.getClass().getSimpleName()+ StringUtils.join(paramList,",");
}
};
}
}
四、注解
4.1 @EnableCaching
启动缓存功能,配置类中需要加上这个注解,有了这个注解以后,spring才知道你需要使用缓存的功能,其他的和缓存相关的注解才会有效,spring中主要是通过aop实现的,通过aop来拦截需要使用缓存的方法,实现缓存的功能
4.2 @Cacheable
根据方法对其返回结果进行缓存(一般用在查询方法上),请求时如果缓存:
- 存在,则直接读取缓存数据返回;
- 不存在,则执行方法,并把返回的结果存入缓存中。
注解相关参数
参数 | 解释 | 示例 |
---|---|---|
value | 缓存的名称,指定存放在哪块命名空间 | @Cacheable(value=“goods”) |
cacheNames | 与Value都说用来指定缓存命名空间的,二选一即可 | @Cacheable(cacheNames=“goods”) |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则默认按照方法的所有参数进行组合 | @Cacheable(value=“goods”,key=“‘goods’+#id”) |
KeyGenerator | 调用key自动生成策略 | @Cacheable(value=“goods”,KeyGenerator=“myKeyGenerator”) |
4.3 @CachePut
能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会执行(一般用在新增方法上)
注解相关参数
参数 | 解释 | 示例 |
---|---|---|
value | 缓存的名称,指定存放在哪块命名空间 | @Cacheable(value=“goods”) |
cacheNames | 与Value都说用来指定缓存命名空间的,二选一即可 | @Cacheable(cacheNames=“goods”) |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则默认按照方法的所有参数进行组合 | @Cacheable(value=“goods”,key=“‘goods’+#id”) |
KeyGenerator | 调用key自动生成策略 | @Cacheable(value=“goods”,KeyGenerator=“myKeyGenerator”) |
4.4 @CacheEvict
能够根据一定的条件对缓存进行清空(一般用在更新或者删除方法上)
注解相关参数
参数 | 解释 | 示例 |
---|---|---|
value | 缓存的名称,指定存放在哪块命名空间 | @Cacheable(value=“goods”) |
cacheNames | 与Value都说用来指定缓存命名空间的,二选一即可 | @Cacheable(cacheNames=“goods”) |
key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则默认按照方法的所有参数进行组合 | @Cacheable(value=“goods”,key=“‘goods’+#id”) |
KeyGenerator | 调用key自动生成策略 | @Cacheable(value=“goods”,KeyGenerator=“myKeyGenerator”) |
allEntries | 是否清空所有缓存内容,默认为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | @CachEvict(value=”goods”,allEntries=true) |
beforeInvocation | 是否在方法执行前就清空,默认为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,默认情况下,如果方法执行抛出异常,则不会清空缓存 | @CachEvict(value=”goods”,beforeInvocation=true) |