问题描述

想在一个JAVA Class 向同一个Redis实例的不同 dbindex 写入数据,非常类似于StackOverflowe上的[How can select dbIndex when I use RedisTemplate in Spring-Data-Redis?。在这篇文章中描述了如何使用Spring boot访问Redis,在创建JedisConnectionFactory的时候指定dbindex:

JedisConnectionFactory factory = new JedisConnectionFactory();
...
factory.setDatabase(databaseId);//set dbindex

因此,大概思路是配置2个RedisTemplate,其中一个RedisTemplate负责访问dbindex=1的数据库;另一个RedisTemplate负责访问dbindex=3的数据库。

根据这篇文章,因此通过 @Bean(name=) 生成多个RedisTemplate。但是由于生成RedisTemplate需要传入JedisConnectionFactory实例,而我们是在JedisConnectionFactory中指定了访问Redis的哪个数据库(dbindex)。因此,就在创建JedisConnectionFactory实例的时候,使用 @Scope(scopeName = "prototype") 注解,这样的话Jedis连接工厂就不再是单例模式了。因此,就有两个JedisConnectionFactory实例,每个实例通过jedisConnectionFactory.setDatabase()设置不同的dbindex。这种方式可能非常愚蠢,会引起严重的性能问题。

下面,来看看具体是怎么配置的:

    @Scope(scopeName = "prototype")
public JedisConnectionFactory jedisConnectionFactory() { JedisPoolConfig config = getRedisConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(config);
factory.setUsePool(true);
factory.setHostName(host);
factory.setPort(port);
return factory;
}

每调用一次jedisConnectionFactory() 返回一个新的JedisConnectionFactory实例。

然后定义2个RedisTemplate Bean,jedisConnectionFactory.setDatabase() 方法分别设置不同的dbindex

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.util.Map; /**
* Created by Administrator on 2018/4/9.
*/ @Configuration
public class LoginMacRedisConfig { private static final Logger logger = LoggerFactory.getLogger(LoginMacRedisConfig.class);
@Value("1")
private int logmacDatabaseId; @Value("3")
private int mobmaskDatabaseId; @Bean
public JedisPoolConfig getRedisConfig() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(8);
config.setMinIdle(0);
return config;
} @Scope(scopeName = "prototype")
public JedisConnectionFactory jedisConnectionFactory() { JedisPoolConfig config = getRedisConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(config);
factory.setUsePool(true);
factory.setHostName(host);
factory.setPort(port);
return factory;
} @Bean(name = "login_mac")
public RedisTemplate<String, Map<String, String>> logmacRedisTemplate() {
final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>(); JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();
jedisConnectionFactory.setDatabase(logmacDatabaseId);
template.setConnectionFactory(jedisConnectionFactory);
logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase()); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
} @Bean(name = "mobile_mask")
public RedisTemplate<String, Map<String, String>> mobileMaskRedisTemplate() {
final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>();
JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();
jedisConnectionFactory.setDatabase(mobmaskDatabaseId);
template.setConnectionFactory(jedisConnectionFactory);
logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase());
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setHashValueSerializer(stringRedisSerializer);
return template;
}
}

最后,再写一个Service类,就可以同时注入这两个RedisTemplate,操作同一个Redis服务器上的不同的dbindex了。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import java.util.HashMap;
import java.util.Map; /**
* Created by Administrator on 2018/4/10.
*/
@Service
public class RedisTestService {
@Autowired
@Qualifier("login_mac")
private RedisTemplate<String, Map<String, String>> template1; @Autowired
@Qualifier("mobile_mask")
private RedisTemplate<String, Map<String, String>> template2; public void write2Redis() {
HashOperations<String, String, String> hashOperations = template1.opsForHash();
Map<String, String> values = new HashMap<>();
values.put("dbindex", "1");
hashOperations.putAll("123", values); template2.opsForHash().put("123", "dbindex", "3");
}
}

Application.java 启动类

@SpringBootApplication
public class Application implements CommandLineRunner{
@Autowired
private RedisTestService redisTestService;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
redisTestService.write2Redis();
}
}

在redisTestService对象中:有两个RedisTemplate实例:

两个RedisTemplate实例分别封装了两个JedisConnectionFactory:

调试结果下:

2018-04-10 20:18:34.754  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:1
2018-04-10 20:19:06.972  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:3

最终查看写入Redis结果,可以看出:dbindex 1 和 dbindex 3 都分别成功写入了数据。

redis 192.168.107.253:6379> SELECT 1
OK
redis 192.168.107.253:6379[1]> KEYS *
1) "123"
redis 192.168.107.253:6379[1]> HGET 123 dbindex
"1"
redis 192.168.107.253:6379[1]> SELECT 3
OK
redis 192.168.107.253:6379[3]> KEYS *
1) "123"
redis 192.168.107.253:6379[3]> HGET 123 dbindex
"3"

额外补充

其实要在同一个应用中访问不同的dbindex,一种方式是使用JedisPool,JedisPool创建Jedis,然后调用select方法选择dbindex。具体实现可参考这篇文章。但这样的话,就不能使用RedisTemplate的各种方便的接口读写Redis了。

    @Bean
public JedisPool redisPoolFactory() {
JedisPool jedisPool = new JedisPool(jedisPoolConfig(), host, port);
Jedis jedis = jedisPool.getResource();
jedis.select(3);
return jedisPool;
}

其实是可以像说的:通过RedisConnectionCommand的 select 方法来选择dbindex的,但是还是同样的问题,用不了RedisTemplate。

RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
DefaultStringRedisConnection stringRedisConnection = new DefaultStringRedisConnection(redisConnection);
stringRedisConnection.select(2);
stringRedisConnection.set("test", "test");

另外这里也有一篇Spring Boot Redis多实例配置,也可以参考一下。Spring Boot 兼Redis新手,只能这样了。

原文:http://www.cnblogs.com/hapjin/p/8783084.html

Spring boot 使用多个RedisTemplate的更多相关文章

  1. 【spring boot】spring boot 基于redis pipeline 管道,批量操作redis命令

    spring boot 2.x 使用RedisTemplate 操作 =================================== 1.pom.xml <!--spring2.0集成r ...

  2. SpringBoot(十一): Spring Boot集成Redis

    1.在 pom.xml 中配置相关的 jar 依赖: <!-- 加载 spring boot redis 包 --> <dependency> <groupId>o ...

  3. spring boot整合reids 然后实现缓存分页(方法之一) 以及RedisTemplate存到reids 里面get 就消失的坑

    业务需求 首页 实现缓存分页 spring boot 整合redis   (我的是2.0.3版本的) 在pom 文件写上依赖包即可 <dependency><!--依赖包--> ...

  4. 曹工说Spring Boot源码(20)-- 码网灰灰,疏而不漏,如何记录Spring RedisTemplate每次操作日志

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...

  5. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  6. spring boot(三):Spring Boot中Redis的使用

    spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...

  7. Spring Boot简介

    Spring Boot简介 Spring Boot是为了简化Spring开发而生,从Spring 3.x开始,Spring社区的发展方向就是弱化xml配置文件而加大注解的戏份.最近召开的SpringO ...

  8. Spring Boot 学习笔记--整合Redis

    1.新建Spring Boot项目 添加spring-boot-starter-data-redis依赖 <dependency> <groupId>org.springfra ...

  9. Spring Boot 整合 Redis 实现缓存操作

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢!   『 产品没有价值,开发团队再优秀也无济于事 – <启示录> 』   本文提纲 ...

随机推荐

  1. 自学华为IoT物联网_09 OceanConnect业务流程

    点击返回自学华为IoT物流网 自学华为IoT物联网_09 OceanConnect业务流程 1.  物流网重要的连个协议介绍 1.1  重要物联网协议介绍----MQTT MQTT(消息队列遥测传输) ...

  2. 【转】gcc 编译使用动态链接库和静态链接库

    1 库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. 有 ...

  3. PHP函数memory_get_usage获取PHP内存清耗量

    (PHP 4 >= 4.3.2, PHP 5, PHP 7) memory_get_usage — 返回分配给 PHP 的内存量 说明 int memory_get_usage ([ bool ...

  4. 牛客寒假算法基础集训营3处女座和小姐姐(三) (数位dp)

    链接:https://ac.nowcoder.com/acm/contest/329/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...

  5. hdu6148 百度之星程序设计竞赛复赛 (数位dp)

    Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. Win10 安装 Linux子系统 Ubuntu18.04 / Kali Linux 的体验

    汇总系列:https://www.cnblogs.com/dunitian/p/4822808.html#linux 几年前就看到新闻,今天周末,突发奇想,家里电脑安装下子系统不就不用安装开发的那些环 ...

  7. javascript Object的新方法

    今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下: 前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列i ...

  8. HDU--5519 Sequence II (主席树)

    题目链接 2016年长春ccpc I 题 题目大意 : 给你n(n≤2∗105n≤2∗105)个数,每个数的大小 0<Ai≤2∗10^5   0<Ai≤2∗10^5. 再给你m(m≤2∗1 ...

  9. Jupyter Notebook的安装

    依赖安装 pandoc texlive-xetex texlive-lang-cjk 安装Jupyter Notebook 本文不讲解在Anaconda中安装. 安装方法 sudo python -m ...

  10. 洛谷P2762 太空飞行计划问题

    这题套路好深......没想渠. 题意:给你若干个设备,若干个任务. 每个任务需要若干设备,设备可重复利用. 完成任务有钱,买设备要钱. 问最大总收益(可以什么任务都不做). 解:最大权闭合子图. 对 ...