springboot2.x+不同索引的redis使用(这里讲缓存redis和redis)
我看了很多文章都是对一个索引进行缓存操作,那如果说我原来的项目本身已经存在redis了,而想增加缓存redis在不同索引中,怎么操作呢?本文就将带领大伙研究不同索引下如何操作;
本文章为原创文章,创作不易,觉得喜欢的朋友点赞加收藏吧
首先创建application.yml文件配置redis。
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=0.0.0.0
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=
# 连接超时时间(毫秒)
spring.redis.timeout=10000
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# Redis数据库索引(这里为1)
spring.redis2.database=1
# Redis服务器地址
spring.redis2.host=0.0.0.0
# Redis服务器连接端口
spring.redis2.port=6379
# Redis服务器连接密码(默认为空)
spring.redis2.password=
# 连接超时时间(毫秒)
spring.redis2.timeout=10000
# 连接池最大连接数(使用负值表示没有限制)
spring.redis2.jedis.pool.max-active=-1
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis2.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis2.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis2.jedis.pool.min-idle=0
然后我在config包中,配置了如下四个类
记得在主类上开启缓存
/**
* 用于自定义redis的基本策略配置
*/
public class RedisConfig {
//注入yml中定义的大小
@Value("${spring.redis.jedis.pool.max-active}")
private int redisPoolMaxActive;
@Value("${spring.redis.jedis.pool.max-wait}")
private int redisPoolMaxWait;
@Value("${spring.redis.jedis.pool.max-idle}")
private int redisPoolMaxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int redisPoolMinIdle;
/**
* 创建redis连接工厂
* @param dbIndex
* @param host
* @param port
* @param password
* @param timeout
* @return
*/
public JedisConnectionFactory createJedisConnectionFactory(int dbIndex, String host, int port, String password, int timeout) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setDatabase(dbIndex);
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setPassword(password);
jedisConnectionFactory.setTimeout(timeout);
jedisConnectionFactory.setPoolConfig(setPoolConfig(redisPoolMaxIdle, redisPoolMinIdle, redisPoolMaxActive, redisPoolMaxWait, true));
return jedisConnectionFactory;
}
/**
* 设置连接池属性
* @param maxIdle
* @param minIdle
* @param maxActive
* @param maxWait
* @param testOnBorrow
* @return
*/
public JedisPoolConfig setPoolConfig(int maxIdle, int minIdle, int maxActive, int maxWait, boolean testOnBorrow) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxTotal(maxActive);
poolConfig.setMaxWaitMillis(maxWait);
poolConfig.setTestOnBorrow(testOnBorrow);
return poolConfig;
}
/**
* json序列化
* @return
*/
public RedisSerializer<Object> jackson2JsonRedisSerializer() {
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//启用默认的类型
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//序列化类,对象映射设置
serializer.setObjectMapper(mapper);
return serializer;
}
/**
* 设置RedisTemplate的序列化方式
* @param redisTemplate
*/
public void setSerializer(RedisTemplate<String,Object> redisTemplate) {
//设置键(key)的序列化方式
redisTemplate.setKeySerializer(jackson2JsonRedisSerializer());
//设置值(value)的序列化方式
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
//设置值(hkey)的序列化方式
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer());
//设置值(hValue)的序列化方式
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
//这里设置redis事务一致
//template.setEnableTransactionSupport(true);
}
}
缓存redis:RedisCacheConfig 的配置
/**
* 缓存redis的自定义配置
*/
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
//自定义 cache key 的生成方式
@Bean
public KeyGenerator simpleKeyGenerator() {
return (o, method, objects) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(o.getClass().getSimpleName());
stringBuilder.append(".");
stringBuilder.append(method.getName());
stringBuilder.append("[");
for (Object obj : objects) {
stringBuilder.append(obj.toString());
}
stringBuilder.append("]");
return stringBuilder.toString();
};
}
//自定义缓存管理策略
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.getRedisCacheConfigurationWithTtl(6L), // 默认策略,未配置的 key 会使用这个
this.getRedisCacheConfigurationMap() // 指定 key 策略
);
}
/* 配置aaa的超时时间为30min*/
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
//记住这里我是设置的aaa,看我下面的例子操作
redisCacheConfigurationMap.put("aaa", this.getRedisCacheConfigurationWithTtl(30L));
return redisCacheConfigurationMap;
}
/* 默认配置超时时间*/
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Long mines) {
RedisConfig redisConfig=new RedisConfig();
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(redisConfig.jackson2JsonRedisSerializer())
)
//当value为null时不进行缓存
.disableCachingNullValues()
// 配置缓存空间名称的前缀
/*.prefixCacheNameWith("demo:")*/
//全局配置缓存过期时间【可以不配置】
.entryTtl(Duration.ofMinutes(mines));
return redisCacheConfiguration;
}
}
配置缓存的的Redis操作实例 到Spring中
/**
* 配置缓存的的Redis操作实例 到Spring中
*/
@Configuration
@EnableCaching
public class LastingRedisConfig extends RedisConfig {
@Value("${spring.redis2.database}")
private int dbIndex;
@Value("${spring.redis2.host}")
private String host;
@Value("${spring.redis2.port}")
private int port;
@Value("${spring.redis2.password}")
private String password;
@Value("${spring.redis2.timeout}")
private int timeout;
/**
* 配置缓存redis连接工厂
*
* @return
*/
@Primary
@Bean
public RedisConnectionFactory lastingRedisConnectionFactory() {
return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
}
/**
* 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
*
* @return
*/
@Bean(name = "lastingRedisTemplate")
//当@Bean没有指定name属性值时,默认使用的是@ConditionalOnMissingBean注解里面的name属性值,且方法名要与其一致。
// 如果不一致,就算@Resource的name属性与@ConditionalOnMissingBean的name属性值一致也不执行以下方法
//而对于@Bean则不需要与方法名一致,只需要使用@Resource时,name属性值写正确即可
/*@ConditionalOnMissingBean(name = "redisTemplate")*/
public RedisTemplate<String,Object> lastingRedisTemplate() {
RedisTemplate<String,Object> template = new RedisTemplate<>();
template.setDefaultSerializer(jackson2JsonRedisSerializer());
template.setConnectionFactory(lastingRedisConnectionFactory());
setSerializer(template);
return template;
}
}
配置默认Redis操作实例 到Spring中
/**
* 配置默认Redis操作实例 到Spring中
*/
@Configuration
public class DefaultRedisConfig extends RedisConfig {
@Value("${spring.redis.database}")
private int dbIndex;
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.timeout}")
private int timeout;
/**
* 配置redis连接工厂
*
* @return
*/
@Bean
public RedisConnectionFactory defaultRedisConnectionFactory() {
return createJedisConnectionFactory(dbIndex, host, port, password, timeout);
}
/**
* 配置redisTemplate 注入方式使用@Resource(name="") 方式注入
*
* @return
*/
@Bean(name = "defaultRedisTemplate")
public RedisTemplate defaultRedisTemplate() {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(defaultRedisConnectionFactory());
setSerializer(template);
return template;
}
}
上面配置好了,接下来就是重点的缓存使用了。(我这里测试的登录功能,将mysql中的数据放入缓存redis中)
@Cacheable(value = "aaa", keyGenerator = "simpleKeyGenerator")
public SmartResult staffLogin(String staffTelNumber, String staffPassword) {
Example example=new Example(Staff.class);
example.createCriteria().andEqualTo("staffTelNumber",staffTelNumber).andEqualTo("staffPassword",DigestUtils.md5DigestAsHex(staffPassword.getBytes()));
List<Staff> staffs=staffMapper.selectByExample(example);
if (staffs.size()==0){
log.error("无相关信息");
return new SmartResult(500,"无相关信息");
}
return SmartResult.ok(staffs);
}
这个代码返回的是SmartResult类(就是封装的返回的状态码,信息,数据)。注意这个类需要实例化
@Test
//测试的登录功能,这是数据库里面存在的
void test4(){
String s="4248058613162109822";
staffService.staffLogin("1831520***","q12345***");
}
由于我上面aaa是在自定义时间30min的缓存中,所以这里显示的是1800s左右
接下来再把aaa换成bbb的话![在这里插入图片描述](https://img-blog.csdnimg.cn/fd2fef62e414499ca467ca084b8bb5f5.png
注意看截图,默认设置的6min中即360s
本篇开头讲到了缓存值存在索引1里面,接下来看下结果
注意上面有个知识点得理解:就是比如我再次执行aaa的话,缓存时间不会被更新,而是等原本aaa的时间过期过后再吧aaa以k,v键值对的形式存进去。
因为缓存redis没有相应的更新策略
觉得可以的话大家可以给个赞吧。