文章目录
前言设置时间传送门
前言
在使用@Cacheable注解时,数据被缓存到redis服务器,但是没有设置失效时间。 查看Cacheable的源码,也没有提供设置缓存时间的属性和办法。如何给缓存设置时间呢?
设置时间
在@Cacheable注解设置时间(cachespace自定义的命名缓存空间,30标识缓存30秒)
@Cacheable(value="cachespace=30",key="#id") //#id表示读取形参里名称为id的值,value表示缓存空间(自定义名称)
public Book queryById(Integer id) {
System.out.println("读取数据库:id="+id);
return bookMapper.selectById(id);
}
需要自定义TtlRedisCacheManager扩展RedisCacheManager
package com.it2.springbootmybatisplus.config;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.util.StringUtils;
import java.time.Duration;
public class TtlRedisCacheManager extends RedisCacheManager {
public TtlRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
}
@Override
protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
System.out.println(name);
String[] cells = StringUtils.delimitedListToStringArray(name, "=");
name = cells[0];
if (cells.length > 1) {
long ttl = Long.parseLong(cells[1]);
// 根据传参设置缓存失效时间,默认单位是秒
cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
}
return super.createRedisCache(name, cacheConfig);
}
}
自定义RedisCacheManager,需要加载到容器中
/**
* 自定义RedisCacheManager,用于在使用@Cacheable时设置ttl
*/
@Bean
public RedisCacheManager selfCacheManager(RedisTemplate
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
return new TtlRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
完整代码
package com.it2.springbootmybatisplus.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@Slf4j
public class MyCacheConfig {
/**
* 定义redis连接池参数,详细参数配置请查阅资料
* */
@Bean
public JedisPoolConfig jedisPool() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(100);
jedisPoolConfig.setMaxWaitMillis(1000);
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMinIdle(10);
return jedisPoolConfig;
}
/**
* 配置Redis的连接,从系统环境变量中取值
* 使用单机部署配置
* */
@Bean
public RedisStandaloneConfiguration jedisConfig() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
int port=(null==System.getenv("REDIS_PORT")?6379:new Integer(System.getenv("REDIS_PORT")));
String hostName=(null==System.getenv("REDIS_HOST")?"127.0.0.1":System.getenv("REDIS_HOST"));
String password=(null==System.getenv("REDIS_PSWD")?null:System.getenv("REDIS_PSWD"));
log.info("Init redis connection - port:{},host:{}",port,hostName);
config.setHostName(hostName);
config.setPort(port);
config.setDatabase(0);
config.setPassword(RedisPassword.of(password));
return config;
}
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPool,
RedisStandaloneConfiguration jedisConfig) {
//配置使用连接池,如果用默认的连接池策略直接builder.build()即可
JedisClientConfiguration jedisClientConfiguration =
JedisClientConfiguration.builder().usePooling().poolConfig(jedisPool).build();
return new JedisConnectionFactory(jedisConfig, jedisClientConfiguration);
}
@Bean
public RedisTemplate
RedisTemplate
template.setConnectionFactory(factory);
// 使用Jackson2JsonRedisSerialize 替换默认的jdkSerializeable序列化
Jackson2JsonRedisSerializer 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);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 自定义RedisCacheManager,用于在使用@Cacheable时设置ttl
*/
@Bean
public RedisCacheManager selfCacheManager(RedisTemplate
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
return new TtlRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
}
}
主类上开启@EnableCaching //开启缓存 启动服务器测试,发起请求,可以看到缓存的TTL不是-1(剩余秒数)
传送门
如果不清楚如何使用@Cacheable,请见 springboot基础(37):spring缓存@Cacheable和@CacheEvict