我是靠谱客的博主 朴素钻石,这篇文章主要介绍RedisTemplate动态切换数据库实现,现在分享给大家,希望可以做个参考。

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

application.properties

复制代码
1
2
3
4
5
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

复制代码
1
2
3
4
5
6
7
8
9
10
LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory(); //切换到指定的数据上 connectionFactory.setDatabase(1); redisTemplate.setConnectionFactory(connectionFactory); //刷新配置 connectionFactory.afterPropertiesSet(); //重置连接 connectionFactory.resetConnection();

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

解决方案:对其加锁

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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配置类

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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配置文件

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

测试类

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
@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动态切换数据库实现内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部