默认redis使用的是db 0,而我们自己在配置连接的时候可以设置默认使用db ,如:
那么怎么去实现动态 去切换自己想使用的db呢?
LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
connectionFactory.setDatabase(num);
依赖
<!-- Redis相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 如果使用Lettuce作为连接池,需要引入commons-pool2包,否则会报错bean注入失败 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
yml
redis:
host: 192.168.222.157
port: 7002
# password: xatgood
database: 0
timeout: 6000 # 连接超时时间(毫秒)默认是2000ms
lettuce:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 100 # 连接池中的最大空闲连接
min-idle: 50 # 连接池中的最小空闲连接
shutdown-timeout: 500
# sentinel: # 哨兵模式
# master: mymaster
# nodes: 192.168.222.155:26379,192.168.222.155:26380,192.168.222.155:26381
# cluster: #集群模式
# nodes:
# - 192.168.222.157:6379
# - 192.168.222.157:6380
# - 192.168.222.157:6381
# - 192.168.222.157:6389
# - 192.168.222.157:6390
# - 192.168.222.157:6391
max-redirects: 3 # 获取失败 最大重定向次数
新建RedisConfig配置类
第一类:
/**
* Redis配置类
*/
@Slf4j
@Configuration
public class RedisConfig {
@Resource
private RedisTemplate redisTemplate;
public RedisTemplate setDataBase(int num) {
LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
if (connectionFactory != null && num != connectionFactory.getDatabase()) {
connectionFactory.setDatabase(num);
this.redisTemplate.setConnectionFactory(connectionFactory);
connectionFactory.resetConnection();
}
return redisTemplate;
}
/**
* 序列化注入spring容器的RedisTemplate
*
* @return
*/
@Bean
public RedisTemplate<Serializable, Object> getRedisTemplate() {
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);
//使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(serializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
// redisTemplate.setEnableTransactionSupport(true);
return redisTemplate;
}
}
第二类
package com.zdyl.wxapplet.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.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.data.redis.connection.*; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Redis配置类 */ @Slf4j @Configuration public class RedisConfig { @Resource private RedisProperties redisProperties; @Resource private RedisTemplate redisTemplate; public static Map<Integer, RedisTemplate<Serializable, Object>> redisTemplateMap = new HashMap<>(); @PostConstruct public void initRedisTemp() throws Exception { for (int i = 0; i <= 15; i++) { redisTemplateMap.put(i, getRedisTemplate(i)); } } /** * 获取redisTemplate实例 * * @param db * @return */ private RedisTemplate<Serializable, Object> getRedisTemplate(int db) { final RedisTemplate<Serializable, Object> redisTemplate = new RedisTemplate<>(); LettuceConnectionFactory factory = factory(); factory.setDatabase(db); redisTemplate.setConnectionFactory(factory); return serializer(redisTemplate); } /** * redis单机配置 * * @return */ private RedisStandaloneConfiguration redisConfiguration() { RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName(redisProperties.getHost()); redisStandaloneConfiguration.setPort(redisProperties.getPort()); //设置密码 if (redisProperties.getPassword() != null) { redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword())); } return redisStandaloneConfiguration; } /** * redis哨兵配置 * * @return */ private RedisSentinelConfiguration getSentinelConfiguration() { RedisProperties.Sentinel sentinel = redisProperties.getSentinel(); if (sentinel != null) { RedisSentinelConfiguration config = new RedisSentinelConfiguration(); config.setMaster(sentinel.getMaster()); if (!StringUtils.isEmpty(redisProperties.getPassword())) { config.setPassword(RedisPassword.of(redisProperties.getPassword())); } config.setSentinels(createSentinels(sentinel)); return config; } return null; } /** * 获取哨兵节点 * * @param sentinel * @return */ private List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) { List<RedisNode> nodes = new ArrayList<>(); for (String node : sentinel.getNodes()) { String[] parts = StringUtils.split(node, ":"); Assert.state(parts.length == 2, "redis哨兵地址配置不合法!"); nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1]))); } return nodes; } /** * redis集群配置 * * @return */ private RedisClusterConfiguration getRedisClusterConfiguration() { RedisProperties.Cluster cluster = redisProperties.getCluster(); if (cluster != null) { RedisClusterConfiguration config = new RedisClusterConfiguration(); config.setClusterNodes(createCluster(cluster)); if (!StringUtils.isEmpty(redisProperties.getPassword())) { config.setPassword(RedisPassword.of(redisProperties.getPassword())); } config.setMaxRedirects(redisProperties.getCluster().getMaxRedirects()); return config; } return null; } /** * 获取集群节点 * * @param cluster * @return */ private List<RedisNode> createCluster(RedisProperties.Cluster cluster) { List<RedisNode> nodes = new ArrayList<>(); for (String node : cluster.getNodes()) { String[] parts = StringUtils.split(node, ":"); Assert.state(parts.length == 2, "redis哨兵地址配置不合法!"); nodes.add(new RedisNode(parts[0], Integer.valueOf(parts[1]))); } return nodes; } /** * 连接池配置 * * @return */ private GenericObjectPoolConfig redisPool() { GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig(); genericObjectPoolConfig.setMaxIdle(redisProperties.getLettuce().getPool().getMaxIdle()); genericObjectPoolConfig.setMinIdle(redisProperties.getLettuce().getPool().getMinIdle()); genericObjectPoolConfig.setMaxTotal(redisProperties.getLettuce().getPool().getMaxActive()); genericObjectPoolConfig.setTestOnBorrow(true); genericObjectPoolConfig.setTestWhileIdle(true); genericObjectPoolConfig.setTestOnReturn(false); genericObjectPoolConfig.setMaxWaitMillis(5000); return genericObjectPoolConfig; } /** * redis客户端配置 * * @return */ private LettuceClientConfiguration clientConfiguration() { LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(); builder.commandTimeout(redisProperties.getLettuce().getShutdownTimeout()); builder.shutdownTimeout(redisProperties.getLettuce().getShutdownTimeout()); builder.poolConfig(redisPool()); LettuceClientConfiguration lettuceClientConfiguration = builder.build(); return lettuceClientConfiguration; } /** * redis获取连接工厂 * * @return */ @Scope(scopeName = "prototype") private LettuceConnectionFactory factory() { //根据配置和客户端配置创建连接 LettuceConnectionFactory lettuceConnectionFactory = null; if (redisProperties.getSentinel() == null && redisProperties.getCluster() == null) { //单机模式 lettuceConnectionFactory = new LettuceConnectionFactory(redisConfiguration(), clientConfiguration()); lettuceConnectionFactory.afterPropertiesSet(); } else if (redisProperties.getCluster() == null) { //哨兵模式 lettuceConnectionFactory = new LettuceConnectionFactory(getSentinelConfiguration(), clientConfiguration()); lettuceConnectionFactory.afterPropertiesSet(); } else { //集群模式 lettuceConnectionFactory = new LettuceConnectionFactory(getRedisClusterConfiguration(), clientConfiguration()); lettuceConnectionFactory.afterPropertiesSet(); } return lettuceConnectionFactory; } /** * 序列化 * * @param redisTemplate * @return */ private RedisTemplate<Serializable, Object> serializer(RedisTemplate redisTemplate) { 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); //使用StringRedisSerializer来序列化和反序列化redis的key值 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(serializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); // redisTemplate.setEnableTransactionSupport(true); return redisTemplate; } }
Redis工具类
/**
* redis工具类
*/
@Slf4j
@Component
public class RedisUtils {
@Resource
private RedisConfig redisConfig;
/**
* 根据db获取对应的redisTemplate实例
*
* @param db
* @return redisTemplate实例
*/
public RedisTemplate<Serializable, Object> getRedisTemplateByDb(final int db) {
return redisConfig.setDataBase(db);
}
/**
* 设置缓存
*
* @param key 缓存key
* @param value 缓存value
*/
public void setString(String key, String value, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
redisTemplate.opsForValue().set(key, value);
log.debug("RedisUtil:set cache key={},value={}", key, value);
}
/**
* 设置缓存,并且自己指定过期时间
*
* @param key
* @param value
* @param expireTime 过期时间
*/
public void setString(String key, String value, int expireTime, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
log.debug("RedisUtil:set cache key={},value={}", key, value, expireTime, TimeUnit.SECONDS);
}
/**
* 设置缓存对象,可指定DB
*
* @param key 缓存key
* @param obj 缓存value
*/
public <T> void setObject(String key, T obj, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
redisTemplate.opsForValue().set(key, obj);
}
/**
* 新增hashMap值
*
* @param key
* @param hashKey
* @param hashValue
* @param db
* @return void
* @author WangJing
* @date 2019年10月26日 9:22
*/
public <T> void hashPutString(Serializable key, Serializable hashKey, String hashValue, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
operations.put(key, hashKey, hashValue);
}
/**
* 以map集合的形式添加键值对
*
* @param key
* @param maps
* @param db
* @return void
* @author Sunhj
* @date 2019年10月26日 9:56
*/
public void hashPutAll(String key, Map<Serializable, Serializable> maps, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
operations.putAll(key, maps);
}
/**
* 获取变量中的键值对
* {key3=value3, key1=value1, key5=value5, key4=value4, key2=value2}
*
* @param db
* @param key
* @return java.util.Map<String, String>
* @author wangj
* @date 2019年10月26日 8:47
*/
public <T> Map<Object, Object> hashGetAll(int db, Serializable key) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForHash().entries(key);
}
/**
* 判断key是否存在
*
* @param key
* @param db
* @return java.util.Map<String, String>
* @author wangj
* @date 2019年10月26日 8:47
*/
public <T> Boolean hashHasKey(Serializable key, Serializable hahsKey, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForHash().hasKey(key, hahsKey);
}
/**
* 获取hash表中存在的所有的键
*
* @param key
* @param db
* @return java.util.List<java.lang.String>
* @author Sunhj
* @date 2019年10月26日 10:58
*/
public Set<Object> hashGetAllHashKeys(Serializable key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForHash().keys(key);
}
/**
* 获取hash表中存在的所有的值
*
* @param key
* @param db
* @return java.util.List<java.lang.String>
* @author Sunhj
* @date 2019年10月26日 10:58
*/
public List<Object> hashGetAllHashValues(Serializable key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForHash().values(key);
}
/**
* 根据key,hashKey
* 获取hash表中存在的单个值
*
* @param key
* @param db
* @return java.util.List<java.lang.String>
* @author Sunhj
* @date 2019年10月26日 10:58
*/
public Object hashGetObject(Serializable key, Serializable hashKey, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForHash().get(key, hashKey);
}
/**
* 删除一个或者多个hash表字段
*
* @param key
* @param db
* @param fields
* @return java.lang.Long
* @author Sunhj
* @date 2019年10月26日 10:15
*/
public Long hashDelete(Serializable key, int db, Serializable... fields) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
return operations.delete(key, (Object) fields);
}
/**
* 删除一个hash表字段
*
* @param key
* @param db
* @param fields
* @return java.lang.Long
* @author Sunhj
* @date 2019年10月26日 10:15
*/
public boolean hashDeleteOne(Serializable key, String fields, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
return operations.delete(key, fields) == 1;
}
/**
* 设置缓存对象
*
* @param key 缓存key
* @param obj 缓存value
*/
public <T> void setObject(String key, T obj, int expireTime, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);
}
/**
* 获取指定key的缓存
*
* @param key---JSON.parseObject(value, User.class);
*/
public Object getObject(String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.opsForValue().get(key);
}
/**
* 判断当前key值 是否存在
*
* @param key
*/
public boolean hasKey(String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
return redisTemplate.hasKey(key);
}
/**
* 获取指定key的缓存
*
* @param key
*/
public String getString(String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
String value = (String) redisTemplate.opsForValue().get(key);
log.debug("RedisUtil:get cache key={},value={}", key, value);
return value;
}
/**
* 删除指定key的缓存
*
* @param key
*/
public void delete(String from, String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
redisTemplate.delete(key);
log.info("RedisUtil:delete " + from + " cache key={}", key);
}
/**
* @param key
* @throws
* @Title: expire
* @Description: 更新key的失效时间
*/
public Boolean expire(String key, int seconds, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
log.debug("RedisUtil:expire cache key={}", key);
return redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
}
/**
* 移除并获取列表中第一个元素
*
* @param key
* @param db
* @return void
* @author sunhj
* @date 2019年10月26日 14:35
*/
public String listLeftPop(Serializable key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
Object leftPop = redisTemplate.opsForList().leftPop(key);
if (leftPop == null) {
return null;
}
return JSON.toJSONString(leftPop);
}
/**
* 移除并获取列表最后一个元素
*
* @param key
* @param db
* @return java.lang.Object
* @author sunhj
* @date 2019年10月26日 14:40
*/
public String listRightPop(Serializable key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
Object x = operations.rightPop(key);
if (x == null) {
return null;
}
return JSON.toJSONString(x);
}
/**
* 获取变量中的指定map键是否有值,如果存在该map键则获取值,没有则返回null。
*
* @param key
* @param field
* @param db
* @return T
* @author Sunhj
* @date 2019年10月26日 8:41
*/
public <T> T hashGet(Serializable key, Serializable field, Class<T> t, int db) {
try {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
//String x = Objects.requireNonNull(operations.get(key, field)).toString();
//T y = JSON.parseObject(Objects.requireNonNull(operations.get(key, field)).toString(), t);
//T y = JSON.parseObject(x , t);
return JSON.parseObject(Objects.requireNonNull(operations.get(key, field)).toString(), t);
} catch (Exception e) {
return null;
}
}
/**
* 获取变量中的指定map键是否有值,如果存在该map键则获取值(String格式),没有则返回null。
*
* @param key
* @param field
* @param db
* @return T
* @author Sunhj
* @date 2019年10月26日 8:41
*/
public String hashGetString(Serializable key, Serializable field, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
try {
Serializable serializable = operations.get(key, field);
if (serializable != null) {
return serializable.toString();
}
return null;
} catch (Exception e) {
log.error("hashGetString方法异常", e);
return null;
}
}
/**
* 获取变量中的键值对 ??
*
* @param key
* @param db
* @return java.util.Map<String, String>
* @author Sunhj
* @date 2019年10月26日 8:47
*/
public <T> Map<String, T> hashGetAll(Serializable key, Class<T> t, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
Map<Serializable, Serializable> x = operations.entries(key);
Map<String, T> map = new HashMap<>();
try {
for (Serializable xa : x.keySet()) {
String keyValue = x.get(xa).toString();
map.put(xa.toString(), JSON.parseObject(keyValue, t));
}
return map;
} catch (Exception e) {
return null;
}
}
/**
* 新增hashMap值
*
* @param key
* @param hashKey
* @param hashValue
* @param db
* @return void
* @author Sunhj
* @date 2019年10月26日 9:22
*/
public <T> boolean hashPut(Serializable key, Serializable hashKey, T hashValue, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
operations.put(key, hashKey, JSON.toJSONString(hashValue, SerializerFeature.WriteMapNullValue));
return true;
}
/**
* 查看hash表中指定字段是否存在
*
* @param key
* @param field
* @param db
* @return boolean
* @author Sunhj
* @date 2019年10月26日 10:32
*/
public boolean hashExists(Serializable key, Serializable field, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
return operations.hasKey(key, field);
}
/**
* 存储在list的头部,即添加一个就把它放在最前面的索引处
*
* @param key
* @param value
* @param db
* @return java.lang.Long
* @author sunhj
* @date 2019年10月26日 14:03
*/
public Long listLeftPush(Serializable key, Serializable value, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
return operations.leftPush(key, value);
}
/**
* 获取所有的KEY
*
* @param key
*/
public List<Object> getHashKeys(String key, int db) {
RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
List<Object> values = redisTemplate.opsForHash().values(key);
return values;
}
}
注意!!!
注意!!!
注意!!!
注意!!!
LettuceConnectionFactory 是 在springboot 2.X版本使用,
但是
springboot 版本 spring-boot-starter-data-redis 的版本对这个redis切换db非常不友好!
亲测 ,使用 springboot 2.1.3.RELEASE springboot 2.1.4.RELEASE springboot 2.1.5.RELEASE 可以成功切换。
但是从springboot 2.1.6.RELEASE 开始 到springboot 2.2.0.RELEASE 都是有问题的。如果有人找到方法了留言告诉一声,我也学习一下!
ok,最后简单的切换使用演示:
@Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class ShaobingApplicationTests { @Resource private RedisUtils redisUtils; @Resource private RedisTemplate redisTemplate; @Test public void testStringRedisTemplate() throws InterruptedException { redisUtils.setObject("1","测试1",1); redisUtils.setObject("2","测试2",2); redisUtils.setObject("3","测试3",3); } }
ok,该篇教程就暂且到此结束。