用idea进行数据同步

  1. 声明对列和交换机

    你需要先在yaml文件当中进行rabbitmq的相关配置

rabbitmq:host:192.168.150.101        //消息件的地址port:5672                   //端口数据username:itcast             //用户名password:123321             //密码virtual-host:/              //虚拟机主机名

声明队列交换机,创建新的工具类,定义不同功能的交换机

public class MqConstants {/*** 交换机*/public final static String HOTEL_EXCHANGE = "hotel.topic";/*** 监听新增和修改的队列*/public final static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";/*** 监听删除的队列*/public final static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";/*** 新增或修改的RoutingKey*/public final static String HOTEL_INSERT_KEY = "hotel.insert";/*** 删除的RoutingKey*/public final static String HOTEL_DELETE_KEY = "hotel.delete";
}
  • 生产者发送消息时,指定交换机为 HOTEL_EXCHANGE 、路由键为 HOTEL_INSERT_KEY 等。

  • 消费者声明队列并绑定到 HOTEL_EXCHANGE 交换机,通过对应的路由键(HOTEL_INSERT_KEY / HOTEL_DELETE_KEY )来订阅特定业务(新增修改 / 删除 )的消息 。

定义队列交换机的对象和绑定关系:

  1. 基于@Bean的方式

    这种方式适合在配置类当中集中管理队列,交换机,绑定关系的 Bean 定义,结构清晰,便于统一维护。

    import org.springframework.amqp.core.*;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    ​
    // 配置类注解,让 Spring 扫描并加载这些 Bean 定义
    @Configuration
    public class RabbitMqConfig {
    ​// 1. 定义交换机(对应 MqConstants 里的交换机)@Beanpublic TopicExchange hotelExchange() {// 创建一个 Topic 类型的交换机,名称用 MqConstants 里的return new TopicExchange(MqConstants.HOTEL_EXCHANGE);}
    ​// 2. 定义“新增和修改”队列@Beanpublic Queue hotelInsertQueue() {return new Queue(MqConstants.HOTEL_INSERT_QUEUE);}
    ​// 3. 定义“删除”队列@Beanpublic Queue hotelDeleteQueue() {return new Queue(MqConstants.HOTEL_DELETE_QUEUE);}
    ​// 4. 绑定“新增和修改”队列到交换机(设置路由键)@Beanpublic Binding bindHotelInsertQueue(TopicExchange hotelExchange, Queue hotelInsertQueue) {// 用 MqConstants 里的新增路由键,将队列绑定到交换机return BindingBuilder.bind(hotelInsertQueue).to(hotelExchange).with(MqConstants.HOTEL_INSERT_KEY);}
    ​// 5. 绑定“删除”队列到交换机(设置路由键)@Beanpublic Binding bindHotelDeleteQueue(TopicExchange hotelExchange, Queue hotelDeleteQueue) {// 用 MqConstants 里的删除路由键,将队列绑定到交换机return BindingBuilder.bind(hotelDeleteQueue).to(hotelExchange).with(MqConstants.HOTEL_DELETE_KEY);}
    }
    • 交换机类型:这里用了 TopicExchange(主题交换机 ),和 MqConstantshotel.topic 对应,也可以根据实际需求换成 DirectExchange(直连 )、FanoutExchange(扇形 / 广播 )等。

    • Bean 依赖注入:绑定方法(如 bindHotelInsertQueue )的参数,会由 Spring 自动注入对应的交换机、队列 Bean,要保证方法参数名或类型能匹配上容器里的 Bean 。

    • 路由键作用:通过 with 方法指定路由键,这样交换机就会根据路由键,把不同业务(新增修改、删除 )的消息路由到对应的队列

    1. 基于注解的方式

      这种方式更灵活,通常在消费者监听方法上直接声明队列、交换机和绑定关系,适合快速开发简单场景,或者临时新增队列绑定的情况。

      import org.springframework.amqp.rabbit.annotation.Exchange;
      import org.springframework.amqp.rabbit.annotation.Queue;
      import org.springframework.amqp.rabbit.annotation.QueueBinding;
      import org.springframework.amqp.rabbit.annotation.RabbitListener;
      import org.springframework.stereotype.Component;
      ​
      @Component // 让 Spring 扫描到这个组件
      public class HotelMqListener {
      ​// 监听“新增和修改”队列,同时声明队列、交换机、绑定关系@RabbitListener(bindings = @QueueBinding(value = @Queue(name = MqConstants.HOTEL_INSERT_QUEUE, durable = "true"), // 声明队列,durable = true 表示持久化exchange = @Exchange(name = MqConstants.HOTEL_EXCHANGE, type = "topic"), // 声明交换机,类型 topickey = MqConstants.HOTEL_INSERT_KEY // 路由键))public void handleHotelInsert(String message) {// 这里写接收到“新增或修改”消息后的业务逻辑,比如更新 Elasticsearch 酒店数据System.out.println("收到酒店新增/修改消息:" + message);}
      ​// 监听“删除”队列,同时声明队列、交换机、绑定关系@RabbitListener(bindings = @QueueBinding(value = @Queue(name = MqConstants.HOTEL_DELETE_QUEUE, durable = "true"),exchange = @Exchange(name = MqConstants.HOTEL_EXCHANGE, type = "topic"),key = MqConstants.HOTEL_DELETE_KEY))public void handleHotelDelete(String message) {// 这里写接收到“删除”消息后的业务逻辑,比如从 Elasticsearch 移除酒店数据System.out.println("收到酒店删除消息:" + message);}
      }
      • 注解参数说明:

        • @Queue:声明队列,name 指定队列名称,durable 设置是否持久化(建议生产环境设为 true ,防止 RabbitMQ 重启队列丢失 )。

        • @Exchange:声明交换机,name 是交换机名称,type 指定类型(如 topicdirectfanout 等 )。

        • @QueueBinding:把队列、交换机、路由键绑定起来,让交换机知道如何把消息路由到这个队列。

      • 消费者方法handleHotelInserthandleHotelDelete 方法就是实际处理消息的逻辑,当对应的队列有消息进来时,方法会被触发执行。

      以下为Rabbitmq的消息发送的代码,当我们在进行增删改等操作的时候,我们只需在其方法内进行消息的发送

       // 新增酒店@PostMappingpublic void saveHotel(@RequestBody Hotel hotel) {hotelService.save(hotel);// 发送新增消息,用新增路由键rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, hotel.getId());}
      ​// 修改酒店@PutMappingpublic void updateById(@RequestBody Hotel hotel) {if (Objects.isNull(hotel.getId())) {throw new InvalidParameterException("id不能为空");}hotelService.updateById(hotel);// 发送修改消息,用修改路由键rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_UPDATE_KEY, hotel.getId());}
      ​// 删除酒店@DeleteMapping("/{id}")public void deleteById(@PathVariable("id") Long id) {hotelService.removeById(id);// 发送删除消息,用删除路由键rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_DELETE_KEY, id);}
      }

      当我们进行消息的发送个时候,我们所需要的参数有。交换机的名字。交换机的路由。需要发送的消息。

消息发送之后,再进行消息的监听。

消息的监听的时候,需要先进行接口的定义,分别定义新增修改和删除的业务接口,可以使用RabbitListener注解进行消息的监听。

 /*** 监听酒店新增或修改队列:从数据库查询最新数据,同步到 Elasticsearch* */@RabbitListener(queues = MqConstants.HOTEL_INSERT_QUEUE)@Transactionalpublic void listenHotelInsertOrUpdate(Long id) {hotelRepository.save(hotel);}
​/*** 监听酒店删除队列:从 Elasticsearch 删除对应酒店数据* @param id 酒店ID*/@RabbitListener(queues = MqConstants.HOTEL_DELETE_QUEUE)@Transactionalpublic void listenHotelDelete(Long id) {// 从 Elasticsearch 删除酒店hotelRepository.deleteById(id);System.out.println("酒店删除,同步 Elasticsearch 成功,酒店ID:" + id);}
定义过接口之后,我们就可以进行方法的实现@Overridepublic void deleteById(Long id) {// 1. 准备Request:创建删除请求,指定索引和文档IDDeleteRequest request = new DeleteRequest(INDEX_NAME, id.toString());
​// 2. 准备发送请求:执行删除操作(这里直接执行,也可做一些请求参数的额外设置,比如超时等)try {DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);if (response.getResult() != null) {System.out.println("Elasticsearch 文档删除成功,文档ID:" + id + ",结果:" + response.getResult());} else {System.err.println("Elasticsearch 文档删除失败,文档ID:" + id);}} catch (Exception e) {e.printStackTrace();System.err.println("删除 Elasticsearch 文档时发生异常,文档ID:" + id + ",异常信息:" + e.getMessage());}}
​@Overridepublic void insertById(Long id) {// 0. 根据id查询酒店数据:从数据库查询Hotel hotel = hotelDbService.getHotelById(id); // 需实现该方法,返回 Hotel 实体if (hotel == null) {System.err.println("根据ID查询酒店数据为空,ID:" + id);return;}
​// 1. 准备Request:创建索引请求,指定索引IndexRequest request = new IndexRequest(INDEX_NAME);request.id(id.toString()); // 设置文档ID,与酒店ID对应
​try {// 将 Hotel 对象转为 JSON 字符串,作为文档内容String hotelJson = objectMapper.writeValueAsString(hotel);request.source(hotelJson, XContentType.JSON);
​// 2. 准备DSL:这里 DSL 已经通过 request.source 等方式设置好了,//    若是复杂场景,可继续添加路由、超时等参数,比如 request.routing("...")
​// 3. 发送请求:执行索引(新增/更新)操作IndexResponse response = client.index(request, RequestOptions.DEFAULT);System.out.println("Elasticsearch 文档插入/更新成功,文档ID:" + id + ",结果:" + response.getResult());} catch (Exception e) {e.printStackTrace();System.err.println("插入/更新 Elasticsearch 文档时发生异常,文档ID:" + id + ",异常信息:" + e.getMessage());}}

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

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

相关文章

实战:Java web应用性能分析之【异步日志:性能优化的金钥匙】

概叙 实战:Java web应用性能分析之【Arthas性能分析trace监控后端性能】-CSDN博客 在优化方面,可以采取以下步骤: ‌性能分析工具‌:使用Arthas或Async Profiler进行实时诊断,定位耗时的方法调用。这可以帮助精确找…

Puppeteer API

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】

【机器学习】Teacher-Student框架

Teacher-Student Setup是一个经典的机器学习框架,包含两个核心角色: 教师模型 (Teacher Model): 通常是一个更大、更强、已经训练好(或正在训练)的模型。它对问题有很好的理解,性能优秀。它的作用是为学生提…

华为云Flexus+DeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型

华为云FlexusDeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型 什么是华为云ModelArts 华为云ModelArts ModelArts是华为云提供的全流程AI开发平台,覆盖从数据准备到模型部署的全生命周期管理,帮助企业和开发…

Web API 路径设计哪家强

本文档主要比较一下各家API的URL路径设计,通过学习各家API的URL路径设计,加深对 REST API 的理解,帮助我们设计出更符合 REST 风格的 API。 Google API 文档地址:https://developers.google.com/apis-explorer/#p/ YouTube Dat…

微信小程序中的计算属性库-miniprogram-computed

miniprogram-computed 是一个用于微信小程序的扩展库,它提供了计算属性(computed)和监听器(watch)的功能,类似于 Vue.js 中的计算属性和监听器。以下是使用 miniprogram-computed 的详细步骤: …

【CSS-7】深入解析CSS伪类:从基础到高级应用

CSS伪类是前端开发中不可或缺的强大工具,它们允许我们根据文档树之外的信息或简单选择器无法表达的状态来样式化元素。本文将全面探讨CSS伪类的各种类型、使用场景和最佳实践。 1. 伪类基础概念 1.1 什么是伪类? 伪类(Pseudo-class&#x…

蓝桥杯国赛训练 day4

目录 再创新高 蓝桥大使 表演赛 次数差 再创新高 import java.math.*; import java.util.*;public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {int t 1; // tsc.nextInt();for(int i0;i<t;i) {solve();}} p…

java 高并发设计

文章目录 目录 文章目录 前言 一、通用设计 一、动静分离 二、数据库独立部署 三、问题 1.高并发通用设计方法 2.高并发系统的拆分顺序 二、计算资源高并发 三、网络资源高并发 超高性能场景&#xff08;10万 QPS&#xff09; 中小规模场景&#xff08;5万 QPS以下&a…

docker compose搭建elk 8.6.2

环境搭建 选用版本是比较新的版本 (ELK) 8.6.2 &#xff0c;elk的环境做的还是比较好的又windows和Linux多个版本&#xff0c;并且开箱即用。本地直接下载官方软件也是可以的。最近在学习docker compose&#xff0c;就使用这个环境搭建一下。 前置条件 安装好docker和 docke…

Springboot3+的id字符串转化问题

以下是纯后端实现 Long/BigInteger ID 转为 JSON 字符串 的详细配置方案&#xff0c;基于 Spring Boot 3 和 SpringDoc (OpenAPI) 最新实践 ✨ 1. 添加依赖 确保你的 pom.xml&#xff08;或 Gradle&#xff09;中包含&#xff1a; <dependency><groupId>com.fast…

C#学习第30天: 匹配模式

模式匹配&#xff08;Pattern Matching&#xff09;是 C# 中一个强大且灵活的特性&#xff0c;允许开发者以更直观的方式检查数据结构&#xff0c;并根据特定模式执行操作。 随着 C# 语言版本的发展&#xff0c;模式匹配的功能越来越丰富&#xff0c;为处理复杂数据提供了极大…

SQL进阶之旅 Day 29:NoSQL结合使用策略

【SQL进阶之旅 Day 29】NoSQL结合使用策略 文章简述 随着数据量的激增和业务场景的复杂化&#xff0c;传统关系型数据库在某些场景下已难以满足高性能、高扩展性和灵活数据结构的需求。NoSQL&#xff08;非关系型数据库&#xff09;以其高可扩展性、灵活的数据模型和分布式架构…

PostgreSQL 对 IPv6 的支持情况

PostgreSQL 对 IPv6 的支持情况 PostgreSQL 全面支持 IPv6 网络协议&#xff0c;包括连接、存储和操作 IPv6 地址。以下是详细说明&#xff1a; 一、网络连接支持 1. 监听 IPv6 连接 在 postgresql.conf 中配置&#xff1a; listen_addresses 0.0.0.0,:: # 监听所有IPv4…

模板字符串使用点击事件【VUE3】

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目中使用模板字符串的时候很多&#xff0c;有些时候需要再模板字符串中使用点击事件&#xff0c;那么在模板字符串中可以使用点击事件么&#xff1f;如果这个点击事件需要传参呢&#xff1f; 答案…

AI——DeepSeek+LangChain+streamlit 实现智能汽车维修服务

效果图 分析流程 代码实现 废话少说&#xff0c;直接上代码 from langchain_core.language_models.llms import BaseLLM from langchain_core.outputs import Generation, LLMResult from pydantic.v1 import Field, validator from typing import Any, Dict, List, Optional…

《C++ 继承》

目录 继承的定义 继承类模板 派生类和基类之前的转换 隐藏 派生类的默认成员函数 不能被继承的类 继承中的友元和静态成员 继承模型 继承的定义 继承的本质是一种复用。规定Person类为基类&#xff0c;Student类为派生类 。 继承方式分为public继承&#xff0c;prote…

金蝶K3 ERP 跨网段访问服务器卡顿问题排查和解决方法

我一朋友公司反应&#xff0c;公司网络卡顿&#xff0c;测试掉包严重&#xff0c;抓包wireshark测试&#xff0c;发现arp包有大量mac欺骗&#xff0c;因为公司有几百台电脑&#xff0c;所以建议更换了三层交换机&#xff0c;划分了vlan&#xff0c;这样有效的避免了网络风暴等&…

无需安装!在线数据库工具 :实战 SQL 语句经典案例

在数字化时代&#xff0c;SQL&#xff08;结构化查询语言&#xff09;已成为数据从业者、开发人员乃至业务分析人员必备的核心技能。无论是处理日常数据报表&#xff0c;还是应对复杂的业务逻辑&#xff0c;SQL 都能高效实现数据的查询、操作与分析。本文将通过经典的 SQL 练习…

如何在网页里填写 PDF下拉框

对于PDF 开发者或网页开发者来说&#xff0c;让用户在网站上填写 PDF 下拉框&#xff08;Combo Box&#xff09;是一个棘手的问题。因为 PDF 并不是一种原生的 Web 格式&#xff0c;浏览器通常不允许用户与 PDF 下拉框进行交互。 那么&#xff0c;如何让用户在 HTML 中填写 PD…