在pom中添加redis缓存支持依赖
org.springframework.boot spring-boot-starter-data-redis
在yml中添加redis配置
设置缓存有效期为一天,配置类中使用
spring: redis: database: xx host: xx.xx.xx.xx port: 6379 password: xxxxx # 密码(默认为空) timeout: 6000ms # 连接超时时长(毫秒) jedis: pool: max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) max-idle: 10 # 连接池中的最大空闲连接 min-idle: 5 # 连接池中的最小空闲连接 activiti: check-process-definitions: false # spirng 缓存管理参数配置 cache: redis: time-to-live: 86400000
修改redis配置类
序列化缓存数据,解决乱码问题(分别配置redisTemplate和注解缓存)
@Configurationpublic class RedisConfig { @Resource private RedisConnectionFactory factory; @Value("${spring.cache.redis.time-to-live}") private Duration timeToLive = Duration.ZERO; /** * 配置Jackson2JsonRedisSerializer序列化策略 * */ private Jackson2JsonRedisSerializer serializer() { // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常// objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer redisSerializer = new StringRedisSerializer(); // 配置序列化(解决乱码的问题) RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() // 缓存有效期 .entryTtl(timeToLive) // 使用StringRedisSerializer来序列化和反序列化redis的key值 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer())) // 禁用空值 .disableCachingNullValues(); return RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); }}
修改VO类,实现序列化接口
实现序列化接口才能将实体类存入缓存中
@Data@TableName("sys_user_token")public class SysUserTokenEntity implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @TableId private Long id; /** * 用户ID */ private Long userId; /** * 用户token */ private String token; /** * 过期时间 */ private Date expireDate; /** * 更新时间 */ private Date updateDate; /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createDate;}
注解缓存类型和用法
@Cacheable
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable(value = CACHE_KEY, key = "#id",condition = "#result != null")public Tasklog findById(String id){ return taskLogMapper.selectById(id);}
@CachePut
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CachePut(value = CACHE_KEY, key = "#tasklog.id")public Tasklog create(Tasklog tasklog){ taskLogMapper.insert(tasklog); return tasklog;}
@CacheEvict
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict(value = CACHE_KEY, key = "#id")public void delete(String id){ taskLogMapper.deleteById(id);}
在项目启动类中上添加@EnableCaching注解,表明启用缓存功能。
@SpringBootApplication@EnableCachingpublic class Ch06CacheApplication { public static void main(String[] args) {SpringApplication.run(Ch06CacheApplication.class, args);}}
注意:设置注解缓存不生效的情形
情形一:
@CachePut注解须加在有返回值的方法上 有些service的实现类中,由于框架的限制,其父类的更新方法是没有返回值的。例如下面的方法中,虽然可以拿到key值,但注解缓存是根据方法的返回值进行更新的,所以会造成数据库更新了数据而缓存中的数据并没有更新。
@Override@Transactional(rollbackFor = Exception.class)@CachePut(value = Constant.UserCacheConstant.USERIDCACHE,key="#dto.id")public void update(WarningRuleDTO dto) { super.update(dto);}
情形二:
加的注解缓存的方法必须是spring通过反射调用的,方法间的调用不会生效。 由于Controller通过反射调用的update方法,继而在调用update2方法,此时缓存注解也是无法生效的。
@Override@Transactional(rollbackFor = Exception.class)public void update(WarningRuleDTO dto) { update2();}@CachePut(value = Constant.UserCacheConstant.USERIDCACHE,key="#dto.id")private WarningRuleDTO update2(WarningRuleDTO dto){ super.update(dto);}
解决方法
既然没办法进行更新操作,那就根据value删除对应的所有key值
@Override@Transactional(rollbackFor = Exception.class)@CacheEvict(value = Constant.UserCacheConstant.USERIDCACHE,allEntries = true)public void update(WarningRuleDTO dto) { super.update(dto);}
作者:zklymm
原文链接:https://www.cnblogs.com/zklymm/p/14030497.html