我是靠谱客的博主 聪明电话,最近开发中收集的这篇文章主要介绍Springboot 2.x 集成redis 同数据源动态切换db,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言:看到一些教程,整合下来存在版本问题或者无法切换数据源,现凭借自己测试整合出适用spring boot2.x版本

yml配置

默认的database 为0

spring:
# redis配置
redis:
host: 192.168.103.195
port: 6379
password: 123456
timeout: 6000
# 连接超时时长(毫秒)
lettuce:
pool:
max-active: 1000
# 连接池最大连接数(使用负值表示没有限制)
max-wait: -1
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10
# 连接池中的最大空闲连接
min-idle: 5
# 连接池中的最小空闲连接

maven配置


<!-- springboot整合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>

我们使用LettuceConnectionFactory 实现动态切换db

LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
connectionFactory.setDatabase(num);

新建RedisConfig配置类

import java.lang.reflect.Method;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.Resource;
@Configuration
@EnableCaching
@RefreshScope
public class RedisConfig extends CachingConfigurerSupport{
@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();
connectionFactory.afterPropertiesSet();
}
return redisTemplate;
}
@RefreshScope
@Bean
public KeyGenerator wiselyKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
@RefreshScope
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
template.afterPropertiesSet();
return template;
}
@RefreshScope
private void setSerializer(StringRedisTemplate template) {
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);
template.setValueSerializer(jackson2JsonRedisSerializer);
}
}

实现单机集群化,


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工具类

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import com.kxyjy.framework.config.RedisConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;
/**
* Created with IntelliJ IDEA.
*
* @author: lenovo
* @createTime: 2022/3/7
* @Time: 11:13
* Description: No Description
*/
@Service
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedisConfig redisConfig;
/**
* 根据前缀获取所有的key
* 例如:pro_*
*/
public Set<String> getListKey(int db) {
redisConfig.setDataBase(db);
Set<String> keys = redisTemplate.keys("*");
return keys;
}
/**
* 设置缓存
*
* @param key
缓存key
* @param value 缓存value
*/
public boolean setString(String key, String value, int db) {
redisConfig.setDataBase(db);
boolean result = false;
try {
redisTemplate.opsForValue().set(key, value);;
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value,int db) {
redisConfig.setDataBase(db);
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime ,TimeUnit timeUnit) {
boolean result = false;
try {
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, timeUnit);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 删除所有的key
* @param
*/
public void removeAll(int db) {
redisConfig.setDataBase(db);
Set<String> keys = redisTemplate.keys("*");
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除对应的value
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
* @param pattern
*/
public void removePattern(final String pattern) {
Set<Serializable> keys = redisTemplate.keys(pattern);
if (keys.size() > 0){
redisTemplate.delete(keys);
}
}
/**
* 删除对应的value
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
* @param key
* @return
*/
public Object get(final String key,int db) {
redisConfig.setDataBase(db);
Object result = null;
ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
/**
* 哈希 添加
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value){
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key,hashKey,value);
}
/**
* 哈希获取数据
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey){
HashOperations<String, Object, Object>
hash = redisTemplate.opsForHash();
return hash.get(key,hashKey);
}
/**
* 列表添加
* @param k
* @param v
*/
public void lPush(String k,Object v){
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k,v);
}
/**
* 列表获取
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1){
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k,l,l1);
}
/**
* 集合添加
* @param key
* @param value
*/
public void add(String key,Object value){
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key,value);
}
/**
* 集合获取
* @param key
* @return
*/
public Set<Object> setMembers(String key){
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key,Object value,double scoure){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key,value,scoure);
}
/**
* 有序集合获取
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key,double scoure,double scoure1){
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
}

最后

以上就是聪明电话为你收集整理的Springboot 2.x 集成redis 同数据源动态切换db的全部内容,希望文章能够帮你解决Springboot 2.x 集成redis 同数据源动态切换db所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(43)

评论列表共有 0 条评论

立即
投稿
返回
顶部