实现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年推出的互联网产品技术外包服务平台。外包大师最新…

MySQL学习——行数计算

数据库经常被用来回答这样的问题&#xff1a;“某种类型的数据在表中出现的频率是多少&#xff1f;”例如&#xff0c;你可能想知道你有多少只宠物&#xff0c;或者每个主人有多少只宠物&#xff0c;或者你可能想对你的动物进行各种类型的人口普查操作。 计算你拥有的动物总数…

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 列表类型 …

零基础入门篇①⑥ Python可变序列类型--字典

Python从入门到精通系列专栏面向零基础以及需要进阶的读者倾心打造,9.9元订阅即可享受付费专栏权益,一个专栏带你吃透Python,专栏分为零基础入门篇、模块篇、网络爬虫篇、Web开发篇、办公自动化篇、数据分析篇…学习不断,持续更新,火热订阅中🔥专栏限时一个月(5.8~6.8)重…

C++STL---deque常见用法

C STL中的deque deque&#xff08;双端队列&#xff09;是C标准模板库&#xff08;STL&#xff09;中的一个序列容器&#xff0c;它允许在容器的前端和后端快速插入和删除元素。与vector相比&#xff0c;deque提供了更灵活的数据结构&#xff0c;特别适合于需要频繁在两端操作…

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

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

智慧公安大数据研判工具(十八)

智慧公安以大数据、云计算、人工智能、物联网和移动互联网技术为支撑&#xff0c;以“打、防、管、控”为目的&#xff0c;综合研判为核心&#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…

go语言方法之方法值和方法表达式

我们经常选择一个方法&#xff0c;并且在同一个表达式里执行&#xff0c;比如常见的p.Distance()形式&#xff0c;实际上 将其分成两步来执行也是可能的。p.Distance叫作“选择器”&#xff0c;选择器会返回一个方法"值"->一 个将方法(Point.Distance)绑定到特定接…

从 AdaBoost 到随机森林:深入解析集成学习方法【集成学习】

集成学习的思想 集成学习是一种通过组合多个基学习器&#xff08;弱学习器&#xff09;来提高模型预测性能的机器学习方法。集成学习的思想类似于谚语“三个臭皮匠&#xff0c;顶个诸葛亮”&#xff0c;即通过集成多个表现较差的学习器&#xff0c;可以获得一个强大的整体模型…

从0开发一个Chrome插件:测试项目效果

前言 这是《从0开发一个Chrome插件》系列的第五篇文章,本系列教你如何从0去开发一个Chrome插件,每篇文章都会好好打磨,写清楚我在开发过程遇到的问题,还有开发经验和技巧。 专栏: 从0开发一个Chrome插件:什么是Chrome插件?从0开发一个Chrome插件:开发Chrome插件的必要…

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注入。…