Spring?Boot集成RabbitMQ以及隊(duì)列模式操作
前言
本篇博客將會(huì)通過我們的實(shí)際場(chǎng)景來演示如何在Spring Boot中集成RabbitMQ以及如何對(duì)各種隊(duì)列模式進(jìn)行操作。
一、場(chǎng)景描述
我們通過模仿用戶下訂單時(shí),訂單系統(tǒng)分別通過短信,郵件或微信進(jìn)行推送消息,如下圖:

二、準(zhǔn)備工作
(1)創(chuàng)建兩個(gè)Spring Boot項(xiàng)目分別對(duì)應(yīng)生產(chǎn)者和消費(fèi)者。
(2)導(dǎo)入依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>(3)定義生產(chǎn)者的配置文件。
application.yml:
server:
port: 8021
spring:
#給項(xiàng)目來個(gè)名字
application:
name: rabbitmq-provider
#配置rabbitMq 服務(wù)器
rabbitmq:
host: 服務(wù)器地址
port: 5672
username: yixin
password: 123456
#虛擬host 可以不設(shè)置,使用server默認(rèn)host
virtual-host: /(4)定義消費(fèi)者的配置文件。
application.yml:
server:
port: 8022
spring:
#給項(xiàng)目來個(gè)名字
application:
name: rabbitmq-consumer
#配置rabbitMq 服務(wù)器
rabbitmq:
host: 服務(wù)器地址
port: 5672
username: yixin
password: 123456
#虛擬host 可以不設(shè)置,使用server默認(rèn)host
virtual-host: /三、發(fā)布/訂閱模式(Fanout)

?? 生產(chǎn)者
項(xiàng)目名:rabbitmq-fanout-provider
(1)編寫配置類。
package com.yixin.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FanoutRabbitConfig {
/**
* 創(chuàng)建三個(gè)隊(duì)列 :fanout.ShortMessage fanout.Email fanout.WeChat
* 將三個(gè)隊(duì)列都綁定在交換機(jī) fanoutExchange 上
* 因?yàn)槭巧刃徒粨Q機(jī), 路由鍵無需配置,配置也不起作用
*/
@Bean
public Queue queueShortMessage() {
// durable:是否持久化,默認(rèn)是false,持久化隊(duì)列:會(huì)被存儲(chǔ)在磁盤上,當(dāng)消息代理重啟時(shí)仍然存在,暫存隊(duì)列:當(dāng)前連接有效
// exclusive:默認(rèn)也是false,只能被當(dāng)前創(chuàng)建的連接使用,而且當(dāng)連接關(guān)閉后隊(duì)列即被刪除。此參考優(yōu)先級(jí)高于durable
// autoDelete:是否自動(dòng)刪除,當(dāng)沒有生產(chǎn)者或者消費(fèi)者使用此隊(duì)列,該隊(duì)列會(huì)自動(dòng)刪除。
// return new Queue("TestDirectQueue",true,true,false);
//一般設(shè)置一下隊(duì)列的持久化就好,其余兩個(gè)就是默認(rèn)false
return new Queue("fanout.ShortMessage",true);
}
@Bean
public Queue queueEmail() {
return new Queue("fanout.Email",true);
}
@Bean
public Queue queueWeChat() {
return new Queue("fanout.WeChat",true);
}
//Fanout交換機(jī) 起名:fanoutExchange
@Bean
FanoutExchange fanoutExchange() {
return new FanoutExchange("fanoutExchange");
}
//綁定 將隊(duì)列和交換機(jī)綁定
@Bean
Binding bindingExchangeShortMessage() {
return BindingBuilder.bind(queueShortMessage()).to(fanoutExchange());
}
@Bean
Binding bindingExchangeEmail() {
return BindingBuilder.bind(queueEmail()).to(fanoutExchange());
}
@Bean
Binding bindingExchangeWeChat() {
return BindingBuilder.bind(queueWeChat()).to(fanoutExchange());
}
}(2)編寫一個(gè)Controller類進(jìn)行推送消息。
package com.yixin.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class OrderController {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,這提供了接收/發(fā)送等等方法
@GetMapping("/sendFanoutMessage")
public String sendFanoutMessage() {
String messageId = String.valueOf(UUID.randomUUID());
String messageData = "用戶成功下單了!";
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String, Object> map = new HashMap<>();
map.put("messageId", messageId);
map.put("messageData", messageData);
map.put("createTime", createTime);
rabbitTemplate.convertAndSend("fanoutExchange", null, map);
return "ok";
}
}?? 消費(fèi)者
項(xiàng)目名:rabbitmq-fanout-consumer
郵件系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "fanout.Email")
public class Email {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("郵件系統(tǒng)收到消息 : " +testMessage.toString());
}
}短信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "fanout.ShortMessage")
public class ShortMessage {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("短信系統(tǒng)收到消息 : " +testMessage.toString());
}
}微信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "fanout.WeChat")
public class WeChat {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("微信系統(tǒng)收到消息 : " +testMessage.toString());
}
}現(xiàn)在我們已經(jīng)創(chuàng)建好了,將rabbitmq-fanout-provider和rabbitmq-fanout-consumer項(xiàng)目都跑起來,在瀏覽器輸入:http://localhost:8021/sendFanoutMessage 進(jìn)行發(fā)送消息。

消費(fèi)者的控制臺(tái)情況如下:

四、Work模式
4.1 輪詢模式
解釋:所謂輪詢分發(fā)就是有兩個(gè)消費(fèi)者監(jiān)聽同一個(gè)隊(duì)列,那么當(dāng)我們發(fā)大量消息的時(shí)候,交換器會(huì)將消息平均分配給兩個(gè)消費(fèi)者,就算其中一個(gè)消費(fèi)者的處理效率比另一個(gè)高,也同樣只能分配一樣的消息數(shù)量。
?? 生產(chǎn)者
(1)編寫配置類。
package com.yixin.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WorkRabbitMQConfig {
@Bean
public Queue queueWork() {
return new Queue("queue_work",true);
}
@Bean
FanoutExchange workExchange() {
return new FanoutExchange("WorkExchange");
}
//綁定 將隊(duì)列和交換機(jī)綁定
@Bean
Binding bindingExchangeShortMessage() {
return BindingBuilder.bind(queueWork()).to(workExchange());
}
}(2)編寫Controller類進(jìn)行推送消息。
package com.yixin.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,這提供了接收/發(fā)送等等方法
@GetMapping("/sendWorkMessage")
public String sendDirectMessage() {
for(int i=0;i<10;i++) {
String message="收到消息:"+i;
//將消息攜帶綁定鍵值:shortmessage 發(fā)送到交換機(jī)DirectExchange
rabbitTemplate.convertAndSend("WorkExchange", "", message);
System.out.println("發(fā)送成功:"+i);
}
return "消息發(fā)送成功!";
}
}?? 消費(fèi)者
郵件系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "queue_work")
public class Email {
@RabbitHandler
public void process(String testMessage) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("郵件系統(tǒng)收到消息 : " +testMessage);
}
}短信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "queue_work")
public class ShortMessage {
@RabbitHandler
public void process(String testMessage) {
//休眠300毫秒,表示效率相比Email低
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("短信系統(tǒng)收到消息 : " +testMessage);
}
}我們把生產(chǎn)者和消費(fèi)者項(xiàng)目都啟動(dòng)起來,訪問 http://localhost:8021/sendWorkMessage 進(jìn)行推送消息:

查看消費(fèi)者的消費(fèi)信息:

可以發(fā)現(xiàn)兩者的工作效率不一樣,但分配到的數(shù)量確實(shí)一樣的,郵件收到的是偶數(shù),短信收到的是奇數(shù),這就是輪詢分發(fā)!
4.2 公平分發(fā)
解讀:公平分發(fā)就是根據(jù)誰執(zhí)行的效率高,那么就給其多分發(fā)消息進(jìn)行處理,正所謂能者多勞。
實(shí)現(xiàn)公平分發(fā)很簡(jiǎn)單,在基于輪詢分發(fā)的基礎(chǔ)上,我們只需要在消費(fèi)者項(xiàng)目的配置文件中加入以下代碼:
spring:
listener:
simple:
prefetch: 1表示將預(yù)處理模式更改為每次讀取1條消息,在消費(fèi)者未回執(zhí)確認(rèn)之前,不在進(jìn)行下一條消息的投送。
故我們的消費(fèi)者的配置文件整體如下:
application.yml:
server:
port: 8022
spring:
application:
name: rabbitmq-consumer
rabbitmq:
host: 服務(wù)器地址
port: 5672
username: yixin
password: 123456
virtual-host: /
listener:
simple:
prefetch: 1我們重新啟動(dòng)生產(chǎn)者和消費(fèi)者項(xiàng)目,消費(fèi)情況如下:

現(xiàn)在可以發(fā)現(xiàn),10條消息,郵件系統(tǒng)消費(fèi)了7條,因?yàn)猷]件系統(tǒng)比短信系統(tǒng)的執(zhí)行效率更高!
五、路由模式(Direct)

?? 生產(chǎn)者
項(xiàng)目名:rabbitmq-direct-provider
(1)編寫配置類。
package com.yixin.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DirectRabbitConfig {
/**
* 創(chuàng)建三個(gè)隊(duì)列 :direct.ShortMessage direct.Email direct.WeChat
* 將三個(gè)隊(duì)列都綁定在交換機(jī) DirectExchange 上
* 因?yàn)槭巧刃徒粨Q機(jī), 路由鍵無需配置,配置也不起作用
*/
@Bean
public Queue queueShortMessage() {
return new Queue("direct.ShortMessage",true);
}
@Bean
public Queue queueEmail() {
return new Queue("direct.Email",true);
}
@Bean
public Queue queueWeChat() {
return new Queue("direct.WeChat",true);
}
//Direct交換機(jī) 起名:DirectExchange
@Bean
DirectExchange DirectExchange() {
return new DirectExchange("DirectExchange",true,false);
}
//綁定 將隊(duì)列和交換機(jī)綁定,并設(shè)置用于匹配鍵
@Bean
Binding bindingExchangeShortMessage() {
return BindingBuilder.bind(queueShortMessage()).to(DirectExchange()).with("shortmessage");
}
@Bean
Binding bindingExchangeEmail() {
return BindingBuilder.bind(queueEmail()).to(DirectExchange()).with("email");
}
@Bean
Binding bindingExchangeWeChat() {
return BindingBuilder.bind(queueWeChat()).to(DirectExchange()).with("wechat");
}
}(2)編寫Controller類進(jìn)行推送消息。
package com.yixin.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,這提供了接收/發(fā)送等等方法
@GetMapping("/sendDirectMessage")
public String sendDirectMessage() {
String messageId = String.valueOf(UUID.randomUUID());
String messageData = "Direct:用戶成功下單了!";
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map=new HashMap<>();
map.put("messageId",messageId);
map.put("messageData",messageData);
map.put("createTime",createTime);
//將消息攜帶綁定鍵值:shortmessage 發(fā)送到交換機(jī)DirectExchange
rabbitTemplate.convertAndSend("DirectExchange", "shortmessage", map);
return "消息發(fā)送成功!";
}
}?? 消費(fèi)者
項(xiàng)目名:rabbitmq-direct-consumer
郵件系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "direct.Email")
public class Email {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("郵件系統(tǒng)收到消息 : " +testMessage.toString());
}
}短信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "direct.ShortMessage")
public class ShortMessage {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("短信系統(tǒng)收到消息 : " +testMessage.toString());
}
}微信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "direct.WeChat")
public class WeChat {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("微信系統(tǒng)收到消息 : " +testMessage.toString());
}
}我們將生產(chǎn)者和消費(fèi)者項(xiàng)目都跑起來,在瀏覽器輸入:http://localhost:8021/sendDirectMessage 進(jìn)行發(fā)送消息。

我們的消費(fèi)者消費(fèi)情況如下:

發(fā)現(xiàn)確實(shí)是只有我們的短信系統(tǒng)收到消息了,測(cè)試成功!
六、主題模式(Topic)

?? 生產(chǎn)者
項(xiàng)目名:rabbitmq-topic-provider
(1)編寫配置類。
package com.yixin.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class TopicRabbitConfig {
@Bean
public Queue queueShortMessage() {
return new Queue("topic.ShortMessage");
}
@Bean
public Queue queueEmail() {
return new Queue("topic.Email");
}
@Bean
public Queue queueWeChat() {
return new Queue("topic.WeChat");
}
@Bean
TopicExchange exchange() {
return new TopicExchange("TopicExchange");
}
//將queueShortMessage和TopicExchange綁定,而且綁定的鍵值為topic.shortmessage
//這樣只要是消息攜帶的路由鍵是topic.shortmessage,才會(huì)分發(fā)到該隊(duì)列
@Bean
Binding bindingExchangeShortMessage() {
return BindingBuilder.bind(queueShortMessage()).to(exchange()).with("topic.shortmessage");
}
//將queueEmail和TopicExchange綁定,而且綁定的鍵值為用上通配路由鍵規(guī)則topic.#
// 這樣只要是消息攜帶的路由鍵是以topic.開頭,都會(huì)分發(fā)到該隊(duì)列
@Bean
Binding bindingExchangeEmail() {
return BindingBuilder.bind(queueEmail()).to(exchange()).with("topic.#");
}
//只要是消息攜帶的路由鍵是topic.wechat,才會(huì)分發(fā)到該隊(duì)列
@Bean
Binding bindingExchangeWeChat() {
return BindingBuilder.bind(queueEmail()).to(exchange()).with("topic.wechat");
}
}(2)編寫Controller類進(jìn)行推送消息。
package com.yixin.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,這提供了接收/發(fā)送等等方法
@GetMapping("/sendTopicMessage")
public String sendDirectMessage() {
String messageId = String.valueOf(UUID.randomUUID());
String messageData = "Topic:用戶成功下單了!";
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String,Object> map=new HashMap<>();
map.put("messageId",messageId);
map.put("messageData",messageData);
map.put("createTime",createTime);
//將消息攜帶綁定鍵值:topic.shortmessage 發(fā)送到交換機(jī)TopicExchange
rabbitTemplate.convertAndSend("TopicExchange", "topic.shortmessage", map);
return "消息發(fā)送成功!";
}
}?? 消費(fèi)者
項(xiàng)目名:rabbitmq-topic-consumer
郵件系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "topic.Email")
public class Email {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("郵件系統(tǒng)收到消息 : " +testMessage.toString());
}
}短信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "topic.ShortMessage")
public class ShortMessage {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("短信系統(tǒng)收到消息 : " +testMessage.toString());
}
}微信系統(tǒng):
package com.yixin.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@RabbitListener(queues = "topic.WeChat")
public class WeChat {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("微信系統(tǒng)收到消息 : " +testMessage.toString());
}
}現(xiàn)在把我們的項(xiàng)目生產(chǎn)者和消費(fèi)者項(xiàng)目啟動(dòng)起來,并輸入http://localhost:8021/sendTopicMessage 進(jìn)行推送消息。

對(duì)我們的消費(fèi)者接受消息的情況進(jìn)行查看:

可以發(fā)現(xiàn)只有我們的郵件和短信系統(tǒng)收到了通知,測(cè)試成功!
小結(jié)
以上就是【一心同學(xué)】整理的如何在【Spring Boot】中集成【RabbitMQ】并且通過【場(chǎng)景演示】在Spring Boot中對(duì)各種【隊(duì)列模式】的使用,大家可以自己動(dòng)手演示一遍,記憶更加深刻。
到此這篇關(guān)于Spring Boot集成RabbitMQ以及隊(duì)列模式操作的文章就介紹到這了,更多相關(guān)SpringBoot集成RabbitMQ內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot集成rabbitMQ之對(duì)象傳輸?shù)姆椒?/a>
- 詳解spring boot集成RabbitMQ
- SpringBoot集成RabbitMQ的方法(死信隊(duì)列)
- spring boot集成rabbitmq的實(shí)例教程
- springboot2.0集成rabbitmq的示例代碼
- Spring boot集成RabbitMQ的示例代碼
- Spring Boot系列教程之7步集成RabbitMQ的方法
- SpringBoot集成RabbitMQ實(shí)現(xiàn)用戶注冊(cè)的示例代碼
- Springboot集成RabbitMQ死信隊(duì)列的實(shí)現(xiàn)
- springboot2.5.6集成RabbitMq實(shí)現(xiàn)Topic主題模式(推薦)
相關(guān)文章
SpringBoot環(huán)境搭建及第一個(gè)程序運(yùn)行(小白教程)
這篇文章主要介紹了SpringBoot環(huán)境搭建及第一個(gè)程序運(yùn)行,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id
這篇文章主要介紹了如何用注解的方式實(shí)現(xiàn)Mybatis插入數(shù)據(jù)時(shí)返回自增的主鍵Id,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
springboot實(shí)現(xiàn)登錄功能的完整步驟
這篇文章主要給大家介紹了關(guān)于springboot實(shí)現(xiàn)登錄功能的完整步驟,在web應(yīng)用程序中,用戶登錄權(quán)限驗(yàn)證是非常重要的一個(gè)步驟,文中通過代碼以及圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
Mybatis 動(dòng)態(tài)表名+Map參數(shù)傳遞+批量操作詳解
這篇文章主要介紹了Mybatis 動(dòng)態(tài)表名+Map參數(shù)傳遞+批量操作詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12
springboot集成ftp實(shí)現(xiàn)文件上傳
這篇文章主要為大家詳細(xì)介紹了springboot集成ftp實(shí)現(xiàn)文件上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
java實(shí)現(xiàn)簡(jiǎn)單的五子棋游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04

