场景

在SpringBoot项目中需要连接两个Redis实例,并实现从A中获取数据并存取到B中。

另外A中redis的地址和密码不能外漏,则将A的地址和密码写在jar包中,B中redis参数可以在外置

配置文件application.yml中进行动态配置。

注:

博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、新建SpringBoot项目并添加依赖

​<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.3.6.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency>​

2、完整的pom文件代码

​
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.7.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.3.0</version></dependency><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.3.6.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>​

3、在配置文件application.properties中配置B的redis的参数

server.port=9090
spring.redis.user.host=另一个redis的地址
spring.redis.user.port=6379
spring.redis.user.password=123456

4、新建Redis的配置类

package com.example.demo.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
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.RedisStandaloneConfiguration;
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;@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {//order@Value("127.0.0.1")private String orderHost;@Value("6379")private String orderPort;@Value("123456")private String orderPassword;//user@Value("${spring.redis.user.host}")private String userHost;@Value("${spring.redis.user.port}")private String userPort;@Value("${spring.redis.user.password}")private String userPassword;private static final int MAX_IDLE = 200; //最大空闲连接数private static final int MAX_TOTAL = 1024; //最大连接数private static final long MAX_WAIT_MILLIS = 10000; //建立连接最长等待时间//配置工厂public RedisConnectionFactory connectionFactory(String host, int port, String password,int index) {RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();redisStandaloneConfiguration.setHostName(host);redisStandaloneConfiguration.setPort(port);redisStandaloneConfiguration.setPassword(password);redisStandaloneConfiguration.setDatabase(index);return new JedisConnectionFactory(redisStandaloneConfiguration);}//连接池配置public JedisPoolConfig poolConfig(int maxIdle, int maxTotal, long maxWaitMillis, boolean testOnBorrow) {JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxIdle(maxIdle);poolConfig.setMaxTotal(maxTotal);poolConfig.setMaxWaitMillis(maxWaitMillis);poolConfig.setTestOnBorrow(testOnBorrow);return poolConfig;}@Bean("redisTemplateOrder")public RedisTemplate<Object, Object> redisTemplateOrder(RedisConnectionFactory connectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory(orderHost, Integer.parseInt(orderPort),orderPassword,0));FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);serializer.setObjectMapper(mapper);template.setValueSerializer(serializer);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.afterPropertiesSet();return template;}@Bean("redisTemplateUser")public RedisTemplate<Object, Object> redisTemplateUser(RedisConnectionFactory connectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory(userHost, Integer.parseInt(userPort),userPassword,0));FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);serializer.setObjectMapper(mapper);template.setValueSerializer(serializer);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.afterPropertiesSet();return template;}
}

注意:

这里连接的是两个Redis,其中A的Redis命名为order,其参数直接在注解中固定赋值。

B的Redis命名为user,参数从配置文件中获取。

这其中又用到了FastJson进行序列化的工具类FastJson2JsonRedisSerializer

package com.example.demo.config;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;import java.nio.charset.Charset;public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{@SuppressWarnings("unused")private ObjectMapper objectMapper = new ObjectMapper();public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");private Class<T> clazz;static{ParserConfig.getGlobalInstance().setAutoTypeSupport(true);}public FastJson2JsonRedisSerializer(Class<T> clazz){super();this.clazz = clazz;}@Overridepublic byte[] serialize(T t) throws SerializationException{if (t == null){return new byte[0];}return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);}@Overridepublic T deserialize(byte[] bytes) throws SerializationException{if (bytes == null || bytes.length <= 0){return null;}String str = new String(bytes, DEFAULT_CHARSET);return JSON.parseObject(str, clazz);}public void setObjectMapper(ObjectMapper objectMapper){Assert.notNull(objectMapper, "'objectMapper' must not be null");this.objectMapper = objectMapper;}protected JavaType getJavaType(Class<?> clazz){return TypeFactory.defaultInstance().constructType(clazz);}
}

5、分别新建两个Redis进行读取操作的service类

RedisServiceOrder:

package com.example.demo;import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;@Component
public class RedisServiceOrder
{@Resource(name = "redisTemplateOrder")public RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value){redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit){redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @returntrue=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout){return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @param unit 时间单位* @returntrue=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit){return redisTemplate.expire(key, timeout, unit);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public boolean deleteObject(final String key){return redisTemplate.delete(key);}/*** 删除集合对象** @param collection 多个对象* @return*/public long deleteObject(final Collection collection){return redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList){Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key){return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> long setCacheSet(final String key, final Set<T> dataSet){Long count = redisTemplate.opsForSet().add(key, dataSet);return count == null ? 0 : count;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key){return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap){if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key){return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key Redis键* @param hKey Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value){redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey){HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();return opsForHash.get(key, hKey);}/*** 获取多个Hash中的数据** @param key Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys){return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(String pattern){return redisTemplate.keys(pattern);}/*** 获得缓存的集合(模糊查询)** @param keys* @return*/public <T> List<T> getCacheList(Set keys) {return redisTemplate.opsForValue().multiGet(keys);}
}

RedisServiceUser:

package com.example.demo;import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;@Component
public class RedisServiceUser
{@Resource(name = "redisTemplateUser")public RedisTemplate redisTemplate;/** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value){redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit){redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @returntrue=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout){return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @param unit 时间单位* @returntrue=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit){return redisTemplate.expire(key, timeout, unit);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public boolean deleteObject(final String key){return redisTemplate.delete(key);}/*** 删除集合对象** @param collection 多个对象* @return*/public long deleteObject(final Collection collection){return redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList){Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key){return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> long setCacheSet(final String key, final Set<T> dataSet){Long count = redisTemplate.opsForSet().add(key, dataSet);return count == null ? 0 : count;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key){return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap){if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key){return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key Redis键* @param hKey Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value){redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey){HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();return opsForHash.get(key, hKey);}/*** 获取多个Hash中的数据** @param key Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys){return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(String pattern){return redisTemplate.keys(pattern);}/*** 获得缓存的集合(模糊查询)** @param keys* @return*/public <T> List<T> getCacheList(Set keys) {return redisTemplate.opsForValue().multiGet(keys);}
}

6、编写测试Controller进行测试

package com.example.demo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/badao")
public class TestController {@Autowiredprivate RedisServiceOrder redisServiceOrder;@Autowiredprivate RedisServiceUser redisServiceUser;@GetMapping("/test")public String list(){redisServiceOrder.setCacheObject("badao","公众号:霸道的程序猿");String badao = redisServiceOrder.getCacheObject("badao");redisServiceUser.setCacheObject("copyBadao",badao);return "公众号:霸道的程序猿";}
}

7、启动项目并调用测试接口

SpringBoot中实现连接多个Redis分别读写数据相关推荐

  1. @transaction使自定义注解失效_【完美】SpringBoot中使用注解来实现 Redis 分布式锁...

    一.业务背景 有些业务请求,属于耗时操作,需要加锁,防止后续的并发操作,同时对数据库的数据进行操作,需要避免对之前的业务造成影响. 二.分析流程 使用 Redis 作为分布式锁,将锁的状态放到 Red ...

  2. 【完美】SpringBoot中使用注解来实现 Redis 分布式锁

    作者:jingQ https://www.sevenyuan.cn/ 一.业务背景 有些业务请求,属于耗时操作,需要加锁,防止后续的并发操作,同时对数据库的数据进行操作,需要避免对之前的业务造成影响. ...

  3. SpringBoot中使用注解来实现 Redis 分布式锁

    我是猿人,一个热爱技术.热爱编程的IT猿.技术是开源的,知识是共享的! 写作是对自己学习的总结和记录,如果您对 Java.分布式.微服务.中间件.Spring Boot.Spring Cloud等技术 ...

  4. mysql sql查询 sleep_mysql中sleep连接过多,Ufiner查询无数据

    一大早上就接到浩子的QQ袭扰,说现场移动的人一堆的投诉,说dms连不上,查询没有数据,都快把他的电话打爆了. 赶紧让浩子登到数据库服务器,确认数据库没有挂掉,进入数据库使用 show processl ...

  5. SpringBoot中利用自定义注解优雅地实现隐私数据脱敏(加密显示)

    前言 这两天在整改等保测出的问题,里面有一个"用户信息泄露"的风险项(就是后台系统里用户的一些隐私数据直接明文显示了),其实指的就是要做数据脱敏. 数据脱敏:把系统里的一些敏感数据 ...

  6. java redis释放连接池_Java 使用连接池操作redis

    构建连接池对象JedisPool JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379); ...

  7. SpringBoot Redis批量存取数据

    springboot中的redisTemplate封装了redis批处理数据的接口,我们使用redisTemplate可以直接进行批量数据的get和set. package com.huateng.a ...

  8. mysql sql 连接查询语句_Mysql——sql数据库中的连接查询

    1.1.1   交叉连接(CROSS JOIN) 交叉连接(CROSS JOIN):有两种,显式的和隐式的,不带ON子句,返回的是两表的乘积,也叫笛卡尔积. 例如:下面的语句1和语句2的结果是相同的. ...

  9. Redis中的连接池以及在Springboot中的使用

    1.为什么要使用连接池以及常用客户端的区别     众所周知,Redis是单线程的,那为什么还要使用连接池?首先Redis也是一种基于内存数据库,有着很高的性能,但是我们的系统使用Redis服务时需要 ...

最新文章

  1. FPGA之道(70)提高设计的综合性能(二)提高设计的自测性
  2. 秒杀 mysql 事务_秒杀怎么样才可以防止超卖?基于mysql的事务和锁实现
  3. 分发 WxWidgets 应用程序
  4. Flink on Zeppelin (4) - 机器学习篇
  5. fckeditor 上传图片 php_fckeditor 上传图片乱码的解决方法_PHP教程
  6. Visual Studio可视化IDE风格主题参照
  7. [2014]Hiring Report of IT Company
  8. 设计psd分层素材模板|家居海报设计思路!
  9. 2016年2月23日----Javascript全局变量和局部变量
  10. 三十二 、K8s审计
  11. (转)switch与ifelse的效率问题 .
  12. html页面加载完成之后,网页加载时页面显示进度条加载完成之后显示网页内容...
  13. multisim常用d触发器_怎么在multisim找D触发器
  14. 为大家介绍两款私藏宝藏可视化大屏制作软件
  15. Android 视频 美颜SDK对比
  16. hackbar小插件
  17. 7-20 表达式转换(中缀转后缀)
  18. 树的应用 —— 树、森林与二叉树的转换
  19. 怎样使盒子上下左右居中
  20. 【Python 爬虫】从入门到放弃(11 个有趣的 Python 爬虫例子)

热门文章

  1. 服务器配置tensorflow2.0.0的gpu环境,python3.7
  2. 初学__Python——Python 自定义函数
  3. java 文件指定位置插入_java中想在一个文件中的某一个位置插入内容,如何操作?...
  4. keras保存模型_onnx+tensorrt部署keras模型
  5. Java后端架构开荒实战(一)——基础设施
  6. jsp 下拉列表选取触发function_Bootstrap下拉菜单样式
  7. textarea 聚焦后边框_textarea焦点的用法实现获取焦点清空失去焦点提示效果
  8. opencv 3和qt5计算机视觉应用开发_【资源分享】有哪些学习openCV的网站或书籍?...
  9. mt.exe : general error c101008d: Failed to write the updated manifest to the resource of file 原因调查
  10. python编程定义圆_Python语言编程系列014——PyQt中自定义圆形指示灯