实现Redis和数据库数据同步问题(JAVA代码实现)

这里我用到了Redis当中的发布订阅模式实现(JAVA代码实现)

先看图示 

        

下面为代码实现

首先将RedisMessageListenerContainer交给Spring管理.

@Configuration
public class redisConfig {@AutowiredRedisConnectionFactory redisConnectionFactory;@Autowired@Qualifier("carServiceDb")private CarService carService;//操作数据库@Beanpublic RedisMessageListenerContainer listenerContainer(){//创建一个Redis消息监听器容器对象RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();//设置Redis连接工厂对象listenerContainer.setConnectionFactory(redisConnectionFactory);//向监听器容器中添加一个监听器,该监听器的主题为INSERTEDlistenerContainer.addMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message, byte[] pattern) {System.out.println("*************insert*************");String carJsonStr = new String(message.getBody());Car car = JSONObject.parseObject(carJsonStr, Car.class);carService.addCar(car);System.out.println(new String(message.getBody()));System.out.println(new String(pattern));System.out.println("*************insert*************");}}, new ChannelTopic(ChannelEnum.INSERTED.name()));//向监听器容器中添加一个监听器,该监听器的主题为UPDATEDlistenerContainer.addMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message, byte[] pattern) {System.out.println("*************UPDATED*************");String carJsonStr = new String(message.getBody());Car car = JSONObject.parseObject(carJsonStr, Car.class);carService.updataCount(car.getBookId(),car.getNumber(),car.getUserId());System.out.println(new String(message.getBody()));System.out.println(new String(pattern));System.out.println("*************UPDATED*************");}}, new ChannelTopic(ChannelEnum.UPDATED.name()));//向监听器容器中添加一个监听器,该监听器的主题为DELETEDlistenerContainer.addMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message, byte[] pattern) {System.out.println("*************DELETED*************");System.out.println(new String(message.getBody()));System.out.println(new String(pattern));List<String[]> strings = JSONArray.parseArray(new String(message.getBody()), String[].class);String[] bookIds = strings.get(0);String userId = strings.get(1)[0];carService.delCar(bookIds,userId);System.out.println("----------------------");System.out.println(Arrays.toString(bookIds));System.out.println(userId);System.out.println("--------delete--------");System.out.println("*************DELETED*************");}}, new ChannelTopic(ChannelEnum.DELETED.name()));return listenerContainer;}
}

          下面代码中的 stringRedisTemplate.convertAndSend();就是发送消息的,其中参数1是发送消息的名称,参数2是发送消息的内容

@Service("carService")
@Slf4j
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements CarService {//购物车hash的Keypublic static final String CAR_KEY = "carKey";//hash购物车中field的前缀public static final String USER_CAR_HASH_FIELD_PREFIX = "car::";@Resourceprivate StringRedisTemplate stringRedisTemplate;/*** 这里存储的时候采用Redis当中的hash存储** @param car*/@Override@Synchronizedpublic void addCar(Car car) {//这里存储的时候采用Redis当中的hash存储HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();//这里field为CAR_HASH_FIELDString userCarKey = USER_CAR_HASH_FIELD_PREFIX + car.getUserId();//Map<String,Car>  键(存储bookId)  值存储购物车某一个商品的信息Map<String, Car> CarMap = null;boolean flag = true;//获得Redis中以存储的当前用户的购物车信息if (opsForHash.hasKey(CAR_KEY, userCarKey)) {//存在当前用户的购物车信息,那么获取原有的数据String carMapJson = opsForHash.get(CAR_KEY, userCarKey);CarMap = JSONObject.parseObject(carMapJson, new TypeReference<Map<String, Car>>() {});//检测当前购物车信息中是否包含新添加上的商品,如果包含则更新数量,如果不包含才新增if (CarMap.containsKey(car.getBookId())) {//获取原先商品的数量Integer BeforeNumber = CarMap.get(car.getBookId()).getNumber();log.info("BeforeNumber==============>{}", BeforeNumber);Integer nowNumber = car.getNumber(); //前端传过来现在的log.info("nowNumber==============>{}", nowNumber);CarMap.get(car.getBookId()).setNumber(BeforeNumber + nowNumber);flag = false; //存在商品//修改//包含才新增 图书的数量 在原有的基础上新增图书的数量} else {//新增//如果不包含当前商品信息 那么直接将商品添加到购物车信息当中CarMap.put(car.getBookId(), car);}} else {/*   新增** 当前的用户的购物车信息不存在*       首先把其添加的商品首先存储到CarMap中* */CarMap = new HashMap<>();CarMap.put(car.getBookId(), car);}//最后将其存入redis当中opsForHash.put(CAR_KEY, userCarKey, JSONObject.toJSONString(CarMap));if (flag){//新增stringRedisTemplate.convertAndSend(ChannelEnum.INSERTED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));}else {//修改stringRedisTemplate.convertAndSend(ChannelEnum.UPDATED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));}}@Overridepublic Collection<Car> getCarList(String userId) {//这里存储的时候采用Redis当中的hash存储HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();String userCarKey = USER_CAR_HASH_FIELD_PREFIX + userId;String jsonStr = opsForHash.get(CAR_KEY, userCarKey);Map<String,Car> CarMap = JSONObject.parseObject(jsonStr, Map.class);return CarMap.values();}@Overridepublic void updataCount(String bookId, int number, String userId) {//这里存储的时候采用Redis当中的hash存储HashOperations<String, String, String> opsForHash = stringRedisTemplate.opsForHash();String userCarKey = USER_CAR_HASH_FIELD_PREFIX + userId;String jsonStr = opsForHash.get(CAR_KEY, userCarKey);Map<String,Car> CarMap = JSONObject.parseObject(jsonStr, new TypeReference<Map<String, Car>>() {});if (!CarMap.containsKey(bookId)){ //不包含return;}Car car = CarMap.get(bookId);car.setNumber(number);//最后将其存入redis当中opsForHash.put(CAR_KEY, userCarKey, JSONObject.toJSONString(CarMap));stringRedisTemplate.convertAndSend(ChannelEnum.UPDATED.name(), JSONObject.toJSONString(CarMap.get(car.getBookId())));}@Overridepublic void delCar(String[] bookIds, String userId) {//获得操作RedisHash的对象HashOperations<String, String, String> forHash = stringRedisTemplate.opsForHash();String userCarKey = USER_CAR_HASH_FIELD_PREFIX+userId;List<String[]> list = new ArrayList<>();//从redis中获取用户对应的购物车数据String carJsonStr = forHash.get(CAR_KEY, userCarKey);//修改指定商品的数量Map<String,Car> carMap = JSONObject.parseObject(carJsonStr, new TypeReference<Map<String,Car>>() {});for(String bookId : bookIds){carMap.remove(bookId);}//将修改后的数据重新添加到redis中forHash.put(CAR_KEY,userCarKey,JSONObject.toJSONString(carMap));list.add(bookIds);list.add(new String[]{userId});stringRedisTemplate.convertAndSend(ChannelEnum.DELETED.name(), JSONObject.toJSONString(list));}
}

上述的两段代码中

第二段代码中stringRedisTemplate.convertAndSend();就是发送消息的,其中参数1是发送消息的名称,参数2是发送消息的内容

第一段代码中的这个就是监听到后接收到的消息,其中参数1{当中的onMessage方法的参数1Message为发送消息的内容,参数2pattern是发送消息的名称}    参数2为监听指定的消息名称(这个要和stringRedisTemplate.convertAndSend()中参数1的要保持一致)

listenerContainer.addMessageListener(new MessageListener() {@Overridepublic void onMessage(Message message, byte[] pattern) {}}, new ChannelTopic(ChannelEnum.INSERTED.name()));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/21100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HALCON-从入门到入门-最常用的算子-二值化

1.废话 图像处理中的二值化是一种将灰度图像转换为只有两种可能值&#xff08;通常是0和255&#xff0c;分别代表黑色和白色&#xff09;的过程。这个过程在数字图像处理中非常常见&#xff0c;因为它可以简化图像数据&#xff0c;突出图像的主要特征&#xff0c;并降低后续处…

【Spring框架全系列】IOC DI案例,setter方法和构造方法注入(详解) + 思维导图

文章目录 一.概念实操Maven父子工程 二. IOC和DI入门案例【重点】1 IOC入门案例【重点】问题导入1.1 门案例思路分析1.2 实现步骤2.1 DI入门案例思路分析2.2 实现步骤2.3 实现代码2.4 图解演示 三、Bean的基础配置问题导入问题导入1 Bean是如何创建的【理解】2 实例化Bean的三种…

二分查找,查找第一个大于目标元素target所对应的下标-2300. 咒语和药水的成功对数

题目链接及描述 2300. 咒语和药水的成功对数 - 力扣&#xff08;LeetCode&#xff09; 题目分析 这道题目作为一个典型的二分查找&#xff0c;题目中所述&#xff0c;找到每一个spells[i]在positions中对应的元素positions[i]使其乘积大于给定元素sucess&#xff0c;并统计每一…

云队友:专业的远程工作和程序员接单平台,用户体验佳

编程赚钱的平台有不少&#xff0c;良莠不齐&#xff0c;今天给大家分享个专业的远程工作平台&#xff0c;以技术类工作为主&#xff08;包括编程&#xff09;&#xff1a; 云队友简介 外包大师是PMCAFF互联网产品社区于2016年推出的互联网产品技术外包服务平台。外包大师最新…

HCIP的学习(28)

第九章&#xff0c;链路聚合和VRRP 链路聚合 ​ 目的&#xff1a;备份链路以及提高链路带宽。 ​ 链路聚合技术&#xff08;Eth-Trunk&#xff09;&#xff1a;将多个物理接口捆绑成一个逻辑接口&#xff0c;将N条物理链路逻辑上聚合为一条逻辑链路。 正常情况下&#xff0c;…

成功解决“IndexError: queue index out of range”错误的全面指南

成功解决“IndexError: queue index out of range”错误的全面指南 引言 在Python编程中&#xff0c;queue模块提供了同步队列类&#xff0c;包括FIFO&#xff08;先进先出&#xff09;队列Queue&#xff0c;LIFO&#xff08;后进先出&#xff09;队列LifoQueue&#xff0c;以…

Redis——基本命令

概念&#xff1a; Redis(REmote Dlctionary Server) 是用 C语言开发的一个开源的高性能键值对(key-value) 数据库 特征&#xff1a; 1. 数据间没有必然的关联关系 2. 内部采用单线程机制进行工作 3. 高性能 4. 多数据类型支持 字符串类型 string 列表类型 …

期权高频交易能做吗?期权可以频繁交易吗?

今天带你了解期权高频交易能做吗&#xff1f;期权可以频繁交易吗&#xff1f;在期权交易市场&#xff0c;大部分人都知道不能频繁交易&#xff0c;就连不少投资新手都知道频繁交易是大忌&#xff0c;是错误的&#xff0c;是应该避免的。所以是不行的。 期权高频交易能做吗&…

阿里云搭建物联网平台+MQTT.fx接入阿里云

文章目录 本篇介绍一、阿里云物联网平台搭建二 、MQTT客户端接入阿里云物联网平台总结 本篇介绍 本篇搭建了阿里云物联网平台&#xff0c;使用MQTT.fx接入阿里云&#xff0c;上传温湿度数据 使用到的软件&#xff1a;阿里云、MQTT.fx 一、阿里云物联网平台搭建 首先创建一个物…

MinIO 使用

MinIO自建对象存储 1、dock-compose 使用dock-compose拉取 minio:image: "minio/minio"container_name: minioports:- "9000:9000"- "9001:9001"volumes:- "./minio/data1:/data1"- "./minio/data2:/data2"restart: on-fai…

Glow模型【图解版加代码】

论文&#xff1a;Glow: Generative Flow with Invertible 1x1 Convolutions 代码&#xff1a;pytorch版本&#xff1a;rosinality/glow-pytorch: PyTorch implementation of Glow (github.com) 正版是TensorFlow版本 openai的 参考csdn文章&#xff1a;Glow-pytorch复现gith…

Cobalt_Strike(CS)渗透工具安装使用到免杀上线

Cobalt_Strike&#xff08;CS&#xff09;安装到免杀上线 原文链接&#xff1a; cs免杀上线 点我 https://mp.weixin.qq.com/s?__bizMzkxNDY5NzMxNw&amp;mid2247483862&amp;idx1&amp;snc6b4da3ce5772a075431098227397baa&amp;chksmc16b3cdcf61cb5ca06f61513…

以sqlilabs靶场为例,讲解SQL注入攻击原理【18-24关】

【less-18】 打开时&#xff0c;获取了自己的IP地址。&#xff0c;通过分析源码知道&#xff0c;会将用户的user-agent作为参数记录到数据库中。 提交的是信息有user-Agent、IP、uname信息。 此时可以借助Burp Suite 工具&#xff0c;修改user_agent&#xff0c;实现sql注入。…

数字水印 | 盲水印嵌入:量化索引机制 QIM

目录 1 什么是量化索引调制&#xff1f;1.1 为什么使用 QIM&#xff1f;1.2 QIM 的算法思想1.3 什么是量化操作&#xff1f;1.4 论文中对 QIM 的介绍 2 盲水印论文中的实际应用2.1 均匀量化器2.2 对论文的分析 &#x1f607;前言&#xff1a;不知道为什么&#xff0c;Q…

Windows下如何把Oracle从C盘整体迁移到D盘?

&#xff08;一&#xff09;写这篇文章的起因 这篇文章适合刚接触的技术小白follow操作&#xff0c;整理文章不易&#xff0c;大家多多点赞转发 起因是昨天有会员在群里发问&#xff0c;客户要把Oracle整个目录从C盘挪到D盘怎么弄 客户那边的人把Oracle整个程序数据文件都安装…

【C++】vector的模拟实现

&#x1f497;个人主页&#x1f497; ⭐个人专栏——C学习⭐ &#x1f4ab;点击关注&#x1f929;一起学习C语言&#x1f4af;&#x1f4ab; 目录 导读 1. vector的核心框架接口 2. 构造函数 2.1 基本构造 2.2 拷贝构造&#xff08;传统写法&#xff09; 2.3 析构函数 2…

《python》poetry install下载缓慢,网络问题断开连接--poetry换源镜像下载

在使用打包工具poetry进行打包的是出现了一个问题就是&#xff0c;在使用poetry进行打包的时候出现了&#xff0c;连接断开这样的问题&#xff0c;这个问题是可以通过换源&#xff0c;通过国内的镜像来解决这个问题就可以了。 找到项目中的pyoroject。toml文件这个文件中写了一…

FJSP:蛇鹫优化算法(SBOA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

详细介绍 FJSP&#xff1a;蛇鹫优化算法&#xff08;Secretary bird optimization algorithm&#xff0c;SBOA&#xff09;求解柔性作业车间调度问题&#xff08;FJSP&#xff09;&#xff0c;提供MATLAB代码-CSDN博客 完整MATLAB代码 FJSP&#xff1a;蛇鹫优化算法&#xff…

设计模式(十三)行为型模式---命令模式(command)

文章目录 命令模式简介结构UML图具体实现UML图代码实现 命令模式简介 命令模式&#xff08;command pattern&#xff09;也叫动作模式或者事务模式。它是将请求&#xff08;命令&#xff09;封装成对象&#xff0c;使得可以用不同的请求对客户端进行参数化&#xff0c;具体的请…

梯度下降: 01.原理与代码实操

1. 简介 梯度下降法(GradientDescent) 算法,不像多元线性回归那样是一个具体做回归任务的算法,而是一个非常通用的优化算法来帮助一些机器学习算法(都是无约束最优化问题)求解出最优解,所谓的通用就是很多机器学习算法都是用梯度下降,甚至深度学习也是用它来求解最优解。…