我是靠谱客的博主 朴素钻石,最近开发中收集的这篇文章主要介绍RedisTemplate动态切换数据库实现,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实现方式一:配置文件方式

application.properties

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.database=1
spring.redis.password=redis123456

通过spring.redis.database属性指定切换数据库

实现方式二:使用LettuceConnectionFactory进行选库

springboot 2.x 版本使用的是LettuceConnectionFactory


LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
//切换到指定的数据上
connectionFactory.setDatabase(1);
redisTemplate.setConnectionFactory(connectionFactory);
//刷新配置
connectionFactory.afterPropertiesSet();
//重置连接
connectionFactory.resetConnection();

LettuceConnectionFactory中的setDatabase方法是线程不安全的,在并发情况下,操作数据时会在不同的redis数据库中混淆。

解决方案:对其加锁


public synchronized static void switchDatabase(int DbIndex) {
LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
//切换到指定的数据上
connectionFactory.setDatabase(DbIndex);
redisTemplate.setConnectionFactory(connectionFactory);
//刷新配置
connectionFactory.afterPropertiesSet();
//重置连接
connectionFactory.resetConnection();
}

使用synchronized关键字加锁会出现线程等待,造成效率低。

使用静态方法会初始化加载到内存,如果后续没被引用,加大了内存负担和程序运行负担,影响程序运行效率。

实现方式三:为每个数据库创建一个RedisTemplate实例

RedisTemplate配置类

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class RedisConfig {
//redis地址
@Value("${redis.host}")
private String host;
//redis端口号
@Value("${redis.port}")
private int port;
//redis密码
@Value("${redis.password}")
private String password;
//默认数据库
private int defaultDB;
//多个数据库集合
@Value("${redis.dbs}")
private List<Integer> dbList;
//RedisTemplate实例
private static Map<Integer, RedisTemplate<String, Object>> redisTemplateMap = new HashMap<>();
/**
* 初始化连接池
*/
@PostConstruct
public void initRedisTemplate() {
defaultDB = dbList.get(0);//设置默认数据库
for (Integer db : dbList) {
//存储多个RedisTemplate实例
redisTemplateMap.put(db, redisTemplate(db));
}
}
public LettuceConnectionFactory redisConnection(int db) {
RedisStandaloneConfiguration server = new RedisStandaloneConfiguration();
server.setHostName(host); // 指定地址
server.setDatabase(db); // 指定数据库
server.setPort(port); //指定端口
server.setPassword(password); //指定密码
LettuceConnectionFactory factory = new LettuceConnectionFactory(server);
factory.afterPropertiesSet(); //刷新配置
return factory;
}
//RedisTemplate模板
public RedisTemplate<String, Object> redisTemplate(int db) {
//为了开发方便,一般直接使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnection(db)); //设置连接
//Json序列化配置
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);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
//hash的key采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
/**
* 指定数据库进行切换
* @param db
数据库索引
* @return
*/
public RedisTemplate<String, Object> getRedisTemplateByDb(int db) {
return redisTemplateMap.get(db);
}
/**
* 使用默认数据库
*
* @return
*/
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplateMap.get(defaultDB);
}
}

properties配置文件

redis.host=127.0.0.1
redis.port=6379
redis.password=redis123456
redis.dbs=0,1,2,3,4,5

测试类

@SpringBootTest
class SpringbootSynchronizedApplicationTests {
@Autowired
private RedisConfig redisConfig;
@Test
void contextLoads() {
//测试使用默认数据库
redisConfig.getRedisTemplate().opsForValue().set("newDatabase","new");
//测试使用指定数据库
redisConfig.getRedisTemplateByDb(3).opsForValue().set("three","three");
}
}

最后

以上就是朴素钻石为你收集整理的RedisTemplate动态切换数据库实现的全部内容,希望文章能够帮你解决RedisTemplate动态切换数据库实现所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部