当前位置: 首页 > news >正文

从0开始搭建一个生产级SpringBoot2.0.X项目(十)SpringBoot 集成RabbitMQ

前言

最近有个想法想整理一个内容比较完整springboot项目初始化Demo。

SpringBoot集成RabbitMQ

 RabbitMQ中的一些角色:

  • publisher:生产者

  • consumer:消费者

  • exchange个:交换机,负责消息路由

  • queue:队列,存储消息

  • virtualHost:虚拟主机,隔离不同租户的exchange、queue、消息的隔离

SpringAMQP是基于RabbitMQ封装的一套模板,并且还利用SpringBoot对其实现了自动装配,使用起来非常方便。 

junit用于测试。

一、pom引入依赖amqp

        <!--rabbitmq--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><scope>test</scope></dependency><!--rabbitmq-->

二、application-dev.yaml 增加RabbitMQ相关配置

spring:#RabbitMQ服务器配置,地址账号密码,virtualhost等配置rabbitmq:host: 127.0.0.1port: 5672username: murgpassword: 123456virtual-host: murg-host#队列中没有消息,阻塞等待时间template:receive-timeout: 2000
logging:level:org.springframework.security: debug

三、发布/订阅

RabbitMQ官方提供了5个不同的Demo示例,对应了不同的消息模型。此处只列举发布/订阅模式。

此模式下根据交换机类型又分为三种。

1.Fanout类型:   广播模式    把消息交给所有绑定到交换机的队列

2.Direct类型:    路由模式     把消息交给符合指定routing key 的队列

3Topic类型:     主题模式      把消息交给符合主题通配符的队列

3.1 Fanout类型

在广播模式下,消息发送流程是这样的:

1) 可以有多个队列

2) 每个队列都要绑定到Exchange(交换机)

3) 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定

4) 交换机把消息发送给绑定过的所有队列

5) 订阅队列的消费者都能拿到消

3.1.1 声明Fanout类型交换机和队列 将交换机和队列绑定在一起

创建配置类FanoutConfig 

声明一个Fanout类型交换机命名为murg.fanout

声明两个Queue队列分别为fanout.queue1和fanout.queue2

分别将两个队列和交换机绑定,后续用于消费消息。

package com.murg.bootdemo.rabbitmq;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Fanout 广播模式下*声明交换机和队列*/
@Configuration
public class FanoutConfig {/*** 声明交换机和队列 将交换机和队列绑定在一起* @return Fanout类型交换机*/@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("murg.fanout");}/*** 第1个队列*/@Beanpublic Queue fanoutQueue1(){return new Queue("fanout.queue1");}/*** 绑定队列和交换机*/@Beanpublic Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}/*** 第2个队列*/@Beanpublic Queue fanoutQueue2(){return new Queue("fanout.queue2");}/*** 绑定队列和交换机*/@Beanpublic Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}

3.1.2创建消息生产服务

创建消息生产服务MessageProducerService ,注入RabbitTemplate 用于发送消息。

 注意一点是rabbittemplate.convertAndSend不会自己创建队列,要先在控制台手动创建一个队列或者再消费者配置中声明一个队列

新增测试广播模式下发送消息方法

package com.murg.bootdemo.rabbitmq;import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;/*** Rabbitmq消息生产者*/
@Service
@RequiredArgsConstructor
public class MessageProducerService {private final RabbitTemplate rabbitTemplate;/*** 测试广播模式下发送消息* @param msg*/public void testFanoutExchange(String msg) {// 发送消息//murg.fanout交换机名字 已经在 FanoutConfig中配置并且初始化了//rabbittemplate.convertAndSend不会自己创建队列,要先在控制台手动创建一个队列或者再消费者配置中声明一个队列rabbitTemplate.convertAndSend("murg.fanout","",msg);}}

3.13创建消息消费服务

创建消息生产服务MessageConsumerService 

@RabbitListener是 SpringAMQP AMQP提供的注解,用于简化 RabbitMQ 消息监听器的创建。通过在方法上添加 @RabbitListener 注解,可以将方法注册为消息监听器用于处理从 RabbitMQ 中接收到的消息。queues 参数定义队列名字 ,此处创建两个监听 在上述FanoutConfig 中已经将这两个队列和交换机murg.fanout绑定,所有可同时消费murg.fanout交换机的消息。

package com.murg.bootdemo.rabbitmq;import lombok.RequiredArgsConstructor;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.ExchangeTypes;
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.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;/*** 消息消费者**/
@Service
@RequiredArgsConstructor
public class MessageConsumerService {/*** 下面是Fanout,广播模式的监听* 通过RabbitListener监听队列名字FanoutConfig 中定义的 fanout.queue1 和fanout.queue2* @param msg*/@RabbitListener(queues = "fanout.queue1")public void listenFanoutQueue1(String msg) {System.out.println("消费者1接收到Fanout消息:【" + msg + "】");}@RabbitListener(queues = "fanout.queue2")public void listenFanoutQueue2(String msg) {System.out.println("消费者2接收到Fanout消息:【" + msg + "】");}}

3.14修改测试类进行测试

修改创建项目时生成的 BootdemoApplicationTests.class

增加以下注解

@ActiveProfiles("dev") 

指定运行环境为开发环境
@RunWith(SpringRunner.class)

指定测试类的运行器(Runner)。其主要作用是将Spring的测试支持集成到JUnit测试中,使得在运行JUnit测试时,Spring的上下文可以被正确地加载和配置。

@SpringBootTest(classes={BootdemoApplication.class})

指定启动类

package com.murg.bootdemo;import com.murg.bootdemo.rabbitmq.MessageProducerService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;@ActiveProfiles("dev")
@RunWith(SpringRunner.class)
@SpringBootTest(classes={BootdemoApplication.class})// 指定启动类
public class BootdemoApplicationTests {@AutowiredMessageProducerService messageProducerService;@Testpublic void contextLoads() {System.out.printf("aaaaaaaaaaaaa");}//测试@Testpublic void testFanoutExchange(){String msg = "遍身罗绮者,不是养蚕人";for (int i=0;i<10;i++){messageProducerService.testFanoutExchange(msg);}}}

3.15 增加一个测试方法调用消息生产服务,发送 Fanout类型的消息。运行测试控制台输出结果

两个队列都可消费。 

3.2 Direct类型

3.2.1MessageProducerService生产服务增加方法testDirectExchange

在Direct模型下:
 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey。
 Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

/*** 测试Direct模式下发送消息* 在Direct模型下:** 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)** 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey。** Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息* murg.Direct* @param msg*/public void testDirectExchange(String msg,String rountingkey) {// 发送消息//murg.fanout交换机名字 已经在 FanoutConfig中配置并且初始化了//rabbittemplate.convertAndSend不会自己创建队列,要先在控制台手动创建一个队列或者再消费者配置中声明一个队列rabbitTemplate.convertAndSend("murg.direct",rountingkey,msg);}

3.2.2MessageConsumerService消费服务增加方法testDirectExchange

Direct模式的消费监听修改队列和交换机的方式改为注解方式。
基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。
在consumer的SpringRabbitListener中添加两个消费者,同时基于注解来声明队列和交换机:@Exchange(name = "murg.direct",type = ExchangeTypes.DIRECT)声明交换机名字及类型
通过key的值声明接收不同路由的消息

direct.queue1 消费 rountingkey为“蚕妇”的消息

direct.queue2 消费 rountingkey为“自京赴奉先县咏怀五百字”的消息

    /**** 下面是rountingKey 路由key 模式的消费监听* 基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。** 在consumer的SpringRabbitListener中添加两个消费者,同时基于注解来声明队列和交换机:**/@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1"),//定义队列名字 direct.queue1exchange = @Exchange(name = "murg.direct", type = ExchangeTypes.DIRECT),//指定交换机和交换机类型key = {"蚕妇"} //指定消费rountingkey))public void listenDirectQueue1(String msg){System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue2"),//定义队列名字 direct.queue2exchange = @Exchange(name = "murg.direct", type = ExchangeTypes.DIRECT),//指定交换机和交换机类型key = {"自京赴奉先县咏怀五百字"}//指定消费rountingkey))public void listenDirectQueue2(String msg){System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");}

3.2.3测试类增加测试方法

    @Testpublic void testDirectExchange() throws InterruptedException {String msg1 = "遍身罗绮者,不是养蚕人";String key1 ="蚕妇";String msg2 = "朱门酒肉臭,路有冻死骨";String key2 ="自京赴奉先县咏怀五百字";for (int i=0;i<10;i++){if (i % 2 == 0){messageProducerService.testDirectExchange(msg2,key2);Thread.sleep(1000);}else {messageProducerService.testDirectExchange(msg1,key1);Thread.sleep(1000);}}}

调用消息生产服务,发送 Direct类型的消息。运行测试控制台输出结果

3.3 Topic类型

3.3.1MessageProducerService生产服务增加方法testTopicExchange

Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!
Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:
#:匹配一个或多个词
*:匹配不多不少恰好1个词
举例:
demo.#:能够匹配demo.spu.insert 或者 demo.spu    #.demo写法也可以
demo.*:只能匹配demo.spu

  public void testTopicExchange(String msg, String key) {rabbitTemplate.convertAndSend("murg.topic",key,msg);}

3.3.2MessageConsumerService消费服务增加方法testDirectExchange

@Exchange(name = "murg.topic",type = ExchangeTypes.TOPIC)声明交换机名字及类型
通过key的值声明接收不同路由的消息

topic.queue1 消费 rountingkey为“罗隐.*”的消息

topic.queue2 消费 rountingkey为“#.贫女”的消息

@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue1"),//定义队列名字 topic.queue1exchange = @Exchange(name = "murg.topic", type = ExchangeTypes.TOPIC),//指定交换机和交换机类型key = {"罗隐.*"} //指定消费rountingkey))public void listenTopicQueue1(String msg){System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue2"),//定义队列名字 topic.queue2exchange = @Exchange(name = "murg.topic", type = ExchangeTypes.TOPIC),//指定交换机和交换机类型key = {"#.贫女"}//指定消费rountingkey))public void listenTopicQueue2(String msg){System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");}

3.3.3测试类增加测试方法 

    @Testpublic void testTopicExchange() throws InterruptedException {String msg = "采得百花成蜜后,为谁辛苦为谁甜";String key ="罗隐.蜂";String msg2 = "苦恨年年压金线,为他人作嫁衣裳";String key2 ="秦韬玉.贫女";for (int i=0;i<10;i++){if (i % 2 == 0){messageProducerService.testTopicExchange(msg,key);Thread.sleep(1000);}else {messageProducerService.testTopicExchange(msg2,key2);Thread.sleep(1000);}}}

调用消息生产服务,发送 Topic类型的消息。运行测试控制台输出结果

相关文章:

从0开始搭建一个生产级SpringBoot2.0.X项目(十)SpringBoot 集成RabbitMQ

前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 SpringBoot集成RabbitMQ RabbitMQ中的一些角色&#xff1a; publisher&#xff1a;生产者 consumer&#xff1a;消费者 exchange个&#xff1a;交换机&#xff0c;负责消息路由 queue&#xff1a;队列…...

GNU/Linux - /proc/sys/vm/drop_caches

/proc/sys/vm/drop_caches 是 Linux 中的一个特殊文件&#xff0c;允许用户释放系统内存中的各种缓存。让我们深入了解一下这项功能的细节&#xff1a; The /proc/sys/vm/drop_caches is a special file in Linux that allows users to free up various caches in the systems …...

ubuntu 22.04 如何调整进程启动后能打开的文件数限制

在 Ubuntu 22.04 中&#xff0c;可以通过修改系统配置来调整进程启动后能够打开的文件数软限制。软限制是指操作系统允许单个进程打开的文件描述符的最大数量。以下是调整该限制的方法&#xff1a; 1. 查看当前限制 首先&#xff0c;你可以通过 ulimit 命令查看当前的软限制和…...

linux基础-完结(详讲补充)

linux基础-完结 一、Linux目录介绍 二、基础命令详细讲解 1. ls&#xff08;列出目录内容&#xff09; 2. cd&#xff08;更改目录&#xff09; 3. clear&#xff08;清除终端屏幕&#xff09; 4. pwd(显示你当前所在的目录) 5. vim(文本编辑器) 6. touch&#xff08;创…...

LoRA:大型语言模型(LLMs)的低秩适应;低秩调整、矩阵的低秩与高秩

目录 LoRA:大型语言模型(LLMs)的低秩适应 一、LoRA的基本原理 二、LoRA的举例说明 三、LoRA的优势 低秩调整、矩阵的低秩与高秩 一、低秩调整(LoRA) 二、矩阵的低秩 三、矩阵的高秩 LoRA:大型语言模型(LLMs)的低秩适应 LoRA(Low-Rank Adaptation of LLMs),…...

游戏引擎学习第四天

视频参考:https://www.bilibili.com/video/BV1aDmqYnEnc/ BitBlt 是 Windows GDI&#xff08;图形设备接口&#xff09;中的一个函数&#xff0c;用于在设备上下文&#xff08;device context, DC&#xff09;之间复制位图数据。BitBlt 的主要用途是将一个图像区域从一个地方复…...

GIT GUI和 GIT bash区别

Git GUI 和 Git Bash 都是与 Git 版本控制工具相关的用户界面&#xff0c;但它们有不同的功能和用途。下面详细说明它们的区别及各自的作用&#xff1a; Git GUI 作用&#xff1a; Git GUI 是一个图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;用于执行 Git 操作。…...

丹摩征文活动|Faster-Rcnn-训练与测试详细教程

本文 丹摩智算平台官方网站的介绍Faster-Rcnn-训练与测试提前准备进行Faster-rcnn 的环境配置数据集的介绍 丹摩智算平台官方网站的介绍 丹摩智算平台&#xff08;DAMODEL&#xff09;是专为人工智能&#xff08;AI&#xff09;开发者打造的高性能计算服务平台&#xff0c;旨在…...

星期-时间范围选择器 滑动选择时间 最小粒度 vue3

星期-时间范围选择器 功能介绍属性说明事件说明实现代码使用范例 根据业务需要&#xff0c;实现了一个可选择时间范围的周视图。用户可以通过鼠标拖动来选择时间段&#xff0c;并且可以通过快速选择组件来快速选择特定的时间范围。 功能介绍 时间范围选择&#xff1a;用户可以…...

一条SQL查询语句的执行流程(MySQL)

第一步&#xff1a;连接器&#xff08;负责跟客户端建立连接、获取权限、维持和管理连接&#xff09; 第二步&#xff1a;查询缓存 之前执行过的查询&#xff0c;MySQL以"Key - Value"的形式存在内存&#xff08;key为SQL&#xff0c;value为结果集&#xff09;&…...

linux基础——详细篇

免责声明 学习视频来自B 站up主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 linux 基础命令重现 cd(切…...

大数据学习10之Hive高级

1.Hive高级 将大的文件按照某一列属性进行GROUP BY 就是分区&#xff0c;只是默认开窗存储&#xff1b; 分区是按行&#xff0c;如一百行数据&#xff0c;按十位上的数字分区&#xff0c;则有十个分区&#xff0c;每个分区里有十行&#xff1b; 分桶是根据某个字段哈希对桶数取…...

MongoDB笔记01-概念与安装

文章目录 前言一、MongoDB相关概念1.1 业务应用场景具体的应用场景什么时候选择MongoDB 1.2 MongoDB简介1.3 体系结构1.4 数据模型1.5 MongoDB的特点 二、本地单机部署2.1 Windows系统中的安装启动第一步&#xff1a;下载安装包第二步&#xff1a;解压安装启动1.命令行参数方式…...

ollama + fastGPT + m3e 本地部署指南

[TOC](ollama fastgptm3e本地部署) 开启WSL 因为这里使用的win部署&#xff0c;所以要安装wsl,如果是linux系统就没那么麻烦 控制面板->程序->程序和功能 更新wsl wsl --set-default-version 2wsl --update --web-download安装ubuntu wsl --install -d Ubuntudoc…...

【设计模式系列】享元模式(十五)

目录 一、什么是享元模式 二、享元模式的角色 三、享元模式的典型应用场景 四、享元模式在ThreadPoolExecutor中的应用 1. 享元对象&#xff08;Flyweight&#xff09;- 工作线程&#xff08;Worker&#xff09; 2. 享元工厂&#xff08;Flyweight Factory&#xff09;- …...

2024大兴区火锅美食节即将开幕——品味多元火锅,点燃冬季消费热潮

为响应“中国国际精品消费月”活动&#xff0c;由大兴区商务局主办、大兴区餐饮行业协会承办的2024大兴区火锅美食节将于11月15日正式启动&#xff0c;为期一个半月的美食盛宴将在大兴区掀起一场冬日的火锅热潮。此次火锅节作为北京市“食在京城、沸腾火锅”火锅美食节的重要组…...

可视化建模与UML《类图实验报告》

史铁生&#xff1a; 余华和莫言扛着我上火车&#xff0c; 推着走打雪仗&#xff0c; 还带我偷西瓜&#xff0c; 被人发现后他们拔腿就跑&#xff0c; 却忘了我还在西瓜地里。 一、实验目的&#xff1a; 1、熟悉类图的构件事物。 2、熟悉类之间的泛化、依赖、聚合和组合关系…...

VS2022项目配置笔记

文章目录 $(ProjectDir&#xff09;与 $(SolutionDir) 宏附加包含目录VC目录和C/C的区别 $(ProjectDir&#xff09;与 $(SolutionDir) 宏 假设有一个解决方案 MySolution&#xff0c;其中包含两个项目 ProjectA 和 ProjectB&#xff0c;目录结构如下&#xff1a; C:\Projects\…...

springboot029基于springboot的网上购物商城系统

&#x1f345;点赞收藏关注 → 添加文档最下方联系方式领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345; 项目视频 基于…...

网站访问在TCP/IP四层模型中的流程

访问一个网站的过程可以通过 TCP/IP 网络模型来描述。TCP/IP 模型通常被分为四层&#xff1a;应用层、传输层、网络层和链路层。以下是从这些层级的角度描述你访问一个网站时所发生的过程&#xff1a; 1. 应用层 (Application Layer) 当你在浏览器中输入一个 URL&#xff08;…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...