Java使用modbus4j實(shí)現(xiàn)modbus?tcp通訊
一、什么是modbus
Modbus是由Modicon(現(xiàn)為施耐德電氣公司的一個(gè)品牌)在1979年發(fā)明的,是全球第一個(gè)真正用于工業(yè)現(xiàn)場(chǎng)的總線協(xié)議。
ModBus網(wǎng)絡(luò)是一個(gè)工業(yè)通信系統(tǒng),由帶智能終端的可編程序控制器和計(jì)算機(jī)通過(guò)公用線路或局部專(zhuān)用線路連接而成。其系統(tǒng)結(jié)構(gòu)既包括硬件、亦包括軟件。它可應(yīng)用于各種數(shù)據(jù)采集和過(guò)程監(jiān)控。
ModBus網(wǎng)絡(luò)只有一個(gè)主機(jī),所有通信都由他發(fā)出。網(wǎng)絡(luò)可支持247個(gè)之多的遠(yuǎn)程從屬控制器,但實(shí)際所支持的從機(jī)數(shù)要由所用通信設(shè)備決定。采用這個(gè)系統(tǒng),各PC可以和中心主機(jī)交換信息而不影響各PC執(zhí)行本身的控制任務(wù)。
二、Java實(shí)現(xiàn)modbus協(xié)議通訊
Java編程中,使用modbus4j實(shí)現(xiàn)Java中的modbus協(xié)議通訊
modbus4j實(shí)現(xiàn)了Java與modbus協(xié)議的以下幾種通訊方式:
- modbus TCP/IP通訊
- modubs UDP/IP通訊
- modbus RTU/IP通訊
核心依賴(lài):
modbus4j.jar
commons-lang3-3.0.jar
下載地址代碼里有
Java讀取工具類(lèi)
package com.leftso.project.demo.modbus4j;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
/**
* modbus通訊工具類(lèi),采用modbus4j實(shí)現(xiàn)
*
* @author lxq
* @dependencies modbus4j-3.0.3.jar
* @website https://github.com/infiniteautomation/modbus4j
*/
public class Modbus4jUtils {
/**
* 工廠。
*/
static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* 獲取master
*
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getMaster() throws ModbusInitException {
IpParameters params = new IpParameters();
params.setHost("localhost");
params.setPort(502);
//
// modbusFactory.createRtuMaster(wapper); //RTU 協(xié)議
// modbusFactory.createUdpMaster(params);//UDP 協(xié)議
// modbusFactory.createAsciiMaster(wrapper);//ASCII 協(xié)議
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 協(xié)議
master.init();
return master;
}
/**
* 讀取[01 Coil Status 0x]類(lèi)型 開(kāi)關(guān)數(shù)據(jù)
*
* @param slaveId
* slaveId
* @param offset
* 位置
* @return 讀取值
* @throws ModbusTransportException
* 異常
* @throws ErrorResponseException
* 異常
* @throws ModbusInitException
* 異常
*/
public static Boolean readCoilStatus(int slaveId, int offset)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 01 Coil Status
BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
Boolean value = getMaster().getValue(loc);
return value;
}
/**
* 讀取[02 Input Status 1x]類(lèi)型 開(kāi)關(guān)數(shù)據(jù)
*
* @param slaveId
* @param offset
* @return
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static Boolean readInputStatus(int slaveId, int offset)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 02 Input Status
BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
Boolean value = getMaster().getValue(loc);
return value;
}
/**
* 讀取[03 Holding Register類(lèi)型 2x]模擬量數(shù)據(jù)
*
* @param slaveId
* slave Id
* @param offset
* 位置
* @param dataType
* 數(shù)據(jù)類(lèi)型,來(lái)自com.serotonin.modbus4j.code.DataType
* @return
* @throws ModbusTransportException
* 異常
* @throws ErrorResponseException
* 異常
* @throws ModbusInitException
* 異常
*/
public static Number readHoldingRegister(int slaveId, int offset, int dataType)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 03 Holding Register類(lèi)型數(shù)據(jù)讀取
BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
Number value = getMaster().getValue(loc);
return value;
}
/**
* 讀取[04 Input Registers 3x]類(lèi)型 模擬量數(shù)據(jù)
*
* @param slaveId
* slaveId
* @param offset
* 位置
* @param dataType
* 數(shù)據(jù)類(lèi)型,來(lái)自com.serotonin.modbus4j.code.DataType
* @return 返回結(jié)果
* @throws ModbusTransportException
* 異常
* @throws ErrorResponseException
* 異常
* @throws ModbusInitException
* 異常
*/
public static Number readInputRegisters(int slaveId, int offset, int dataType)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 04 Input Registers類(lèi)型數(shù)據(jù)讀取
BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
Number value = getMaster().getValue(loc);
return value;
}
/**
* 批量讀取使用方法
*
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static void batchRead() throws ModbusTransportException, ErrorResponseException, ModbusInitException {
BatchRead<Integer> batch = new BatchRead<Integer>();
batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(1, BaseLocator.inputStatus(1, 0));
ModbusMaster master = getMaster();
batch.setContiguousRequests(false);
BatchResults<Integer> results = master.send(batch);
System.out.println(results.getValue(0));
System.out.println(results.getValue(1));
}
/**
* 測(cè)試
*
* @param args
*/
public static void main(String[] args) {
try {
// 01測(cè)試
Boolean v011 = readCoilStatus(1, 0);
Boolean v012 = readCoilStatus(1, 1);
Boolean v013 = readCoilStatus(1, 6);
System.out.println("v011:" + v011);
System.out.println("v012:" + v012);
System.out.println("v013:" + v013);
// 02測(cè)試
Boolean v021 = readInputStatus(1, 0);
Boolean v022 = readInputStatus(1, 1);
Boolean v023 = readInputStatus(1, 2);
System.out.println("v021:" + v021);
System.out.println("v022:" + v022);
System.out.println("v023:" + v023);
// 03測(cè)試
Number v031 = readHoldingRegister(1, 1, DataType.FOUR_BYTE_FLOAT);// 注意,float
Number v032 = readHoldingRegister(1, 3, DataType.FOUR_BYTE_FLOAT);// 同上
System.out.println("v031:" + v031);
System.out.println("v032:" + v032);
// 04測(cè)試
Number v041 = readInputRegisters(1, 1, DataType.FOUR_BYTE_FLOAT);//
Number v042 = readInputRegisters(1, 3, DataType.FOUR_BYTE_FLOAT);//
System.out.println("v041:" + v041);
System.out.println("v042:" + v042);
// 批量讀取
batchRead();
} catch (Exception e) {
e.printStackTrace();
}
}
}三、測(cè)試
使用ModbusSlave模擬modbus協(xié)議
slave中模擬數(shù)據(jù)如下
運(yùn)行工具類(lèi)的main方法:
11:14:54.547 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 01 00 00 00 01
11:14:54.550 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.598 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 01 01 01
11:14:54.600 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 01 00 01 00 01
11:14:54.600 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.650 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 01 01 00
11:14:54.652 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 01 00 06 00 01
11:14:54.652 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.703 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 01 01 01
v011:true
v012:false
v013:true
11:14:54.704 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 02 00 00 00 01
11:14:54.704 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.755 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 02 01 01
11:14:54.757 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 02 00 01 00 01
11:14:54.757 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.807 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 02 01 00
11:14:54.810 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 02 00 02 00 01
11:14:54.810 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.860 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 02 01 01
v021:true
v022:false
v023:true
11:14:54.866 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 03 00 01 00 02
11:14:54.866 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.915 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 07 01 03 04 40 20 00 00
11:14:54.917 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 03 00 03 00 02
11:14:54.917 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:54.967 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 07 01 03 04 41 28 00 00
v031:2.5
v032:10.5
11:14:54.971 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 04 00 01 00 02
11:14:54.971 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:55.020 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 07 01 04 04 3F C0 00 00
11:14:55.021 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 04 00 03 00 02
11:14:55.021 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:55.072 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 07 01 04 04 40 40 00 00
v041:1.5
v042:3.0
11:14:55.074 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 00 00 00 00 06 01 02 00 00 00 01
11:14:55.074 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:55.123 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 00 00 00 00 04 01 02 01 01
11:14:55.125 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Encap Request: 00 01 00 00 00 06 01 03 00 01 00 02
11:14:55.125 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Sending on port: 502
11:14:55.179 [main] DEBUG com.serotonin.modbus4j.ip.tcp.TcpMaster - Response: 00 01 00 00 00 07 01 03 04 40 20 00 00
2.5
true
觀察輸出結(jié)果與 slave上的模擬數(shù)據(jù)一致
四、Java通過(guò)modbus4j對(duì)數(shù)據(jù)的寫(xiě)入
Modbus4jWriteUtils.java
package com.leftso.project.demo.modbus4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.ModbusResponse;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
import com.serotonin.modbus4j.msg.WriteRegisterRequest;
import com.serotonin.modbus4j.msg.WriteRegisterResponse;
import com.serotonin.modbus4j.msg.WriteRegistersRequest;
/**
* modbus4j寫(xiě)入數(shù)據(jù)
*
* @author xq
*
*/
public class Modbus4jWriteUtils {
static Log log = LogFactory.getLog(Modbus4jWriteUtils.class);
/**
* 工廠。
*/
static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* 獲取tcpMaster
*
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getMaster() throws ModbusInitException {
IpParameters params = new IpParameters();
params.setHost("localhost");
params.setPort(502);
ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, false);
tcpMaster.init();
return tcpMaster;
}
/**
* 寫(xiě) [01 Coil Status(0x)]寫(xiě)一個(gè) function ID = 5
*
* @param slaveId
* slave的ID
* @param writeOffset
* 位置
* @param writeValue
* 值
* @return 是否寫(xiě)入成功
* @throws ModbusTransportException
* @throws ModbusInitException
*/
public static boolean writeCoil(int slaveId, int writeOffset, boolean writeValue)
throws ModbusTransportException, ModbusInitException {
// 獲取master
ModbusMaster tcpMaster = getMaster();
// 創(chuàng)建請(qǐng)求
WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
// 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象
WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
if (response.isException()) {
return false;
} else {
return true;
}
}
/**
* 寫(xiě)[01 Coil Status(0x)] 寫(xiě)多個(gè) function ID = 15
*
* @param slaveId
* slaveId
* @param startOffset
* 開(kāi)始位置
* @param bdata
* 寫(xiě)入的數(shù)據(jù)
* @return 是否寫(xiě)入成功
* @throws ModbusTransportException
* @throws ModbusInitException
*/
public static boolean writeCoils(int slaveId, int startOffset, boolean[] bdata)
throws ModbusTransportException, ModbusInitException {
// 獲取master
ModbusMaster tcpMaster = getMaster();
// 創(chuàng)建請(qǐng)求
WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, bdata);
// 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象
WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
if (response.isException()) {
return false;
} else {
return true;
}
}
/***
* 寫(xiě)[03 Holding Register(4x)] 寫(xiě)一個(gè) function ID = 6
*
* @param slaveId
* @param writeOffset
* @param writeValue
* @return
* @throws ModbusTransportException
* @throws ModbusInitException
*/
public static boolean writeRegister(int slaveId, int writeOffset, short writeValue)
throws ModbusTransportException, ModbusInitException {
// 獲取master
ModbusMaster tcpMaster = getMaster();
// 創(chuàng)建請(qǐng)求對(duì)象
WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue);
WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request);
if (response.isException()) {
log.error(response.getExceptionMessage());
return false;
} else {
return true;
}
}
/**
*
* 寫(xiě)入[03 Holding Register(4x)]寫(xiě)多個(gè) function ID=16
*
* @param slaveId
* modbus的slaveID
* @param startOffset
* 起始位置偏移量值
* @param sdata
* 寫(xiě)入的數(shù)據(jù)
* @return 返回是否寫(xiě)入成功
* @throws ModbusTransportException
* @throws ModbusInitException
*/
public static boolean writeRegisters(int slaveId, int startOffset, short[] sdata)
throws ModbusTransportException, ModbusInitException {
// 獲取master
ModbusMaster tcpMaster = getMaster();
// 創(chuàng)建請(qǐng)求對(duì)象
WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, sdata);
// 發(fā)送請(qǐng)求并獲取響應(yīng)對(duì)象
ModbusResponse response = tcpMaster.send(request);
if (response.isException()) {
log.error(response.getExceptionMessage());
return false;
} else {
return true;
}
}
/**
* 寫(xiě)入數(shù)字類(lèi)型的模擬量(如:寫(xiě)入Float類(lèi)型的模擬量、Double類(lèi)型模擬量、整數(shù)類(lèi)型Short、Integer、Long)
*
* @param slaveId
* @param offset
* @param value
* 寫(xiě)入值,Number的子類(lèi),例如寫(xiě)入Float浮點(diǎn)類(lèi)型,Double雙精度類(lèi)型,以及整型short,int,long
* @param registerCount
* ,com.serotonin.modbus4j.code.DataType
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static void writeHoldingRegister(int slaveId, int offset, Number value, int dataType)
throws ModbusTransportException, ErrorResponseException, ModbusInitException {
// 獲取master
ModbusMaster tcpMaster = getMaster();
// 類(lèi)型
BaseLocator<Number> locator = BaseLocator.holdingRegister(slaveId, offset, dataType);
tcpMaster.setValue(locator, value);
}
public static void main(String[] args) {
try {
//@formatter:off
// 測(cè)試01
// boolean t01 = writeCoil(1, 0, true);
// System.out.println("T01:" + t01);
// 測(cè)試02
// boolean t02 = writeCoils(1, 0, new boolean[] { true, false, true });
// System.out.println("T02:" + t02);
// 測(cè)試03
// short v = -3;
// boolean t03 = writeRegister(1, 0, v);
// System.out.println("T03:" + t03);
// 測(cè)試04
// boolean t04 = writeRegisters(1, 0, new short[] { -3, 3, 9 });
// System.out.println("t04:" + t04);
//寫(xiě)模擬量
writeHoldingRegister(1,0, 10.1f, DataType.FOUR_BYTE_FLOAT);
//@formatter:on
} catch (Exception e) {
e.printStackTrace();
}
}
}以上就是Java使用modbus4j實(shí)現(xiàn)modbus tcp通訊的詳細(xì)內(nèi)容,更多關(guān)于Java modbus tcp通訊的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用SpringBoot實(shí)現(xiàn)高效的文件分塊上傳方案
在互聯(lián)網(wǎng)應(yīng)用中,大文件上傳是一個(gè)常見(jiàn)而棘手的挑戰(zhàn),傳統(tǒng)的單文件上傳方式在面對(duì)大文件時(shí)經(jīng)常面臨超時(shí)、內(nèi)存溢出等問(wèn)題,本文將深入探討如何利用Spring Boot實(shí)現(xiàn)高效的分塊上傳方案,解決大文件傳輸痛點(diǎn),需要的朋友可以參考下2025-06-06
如何用IDEA+Docker一鍵部署項(xiàng)目SpringBoot項(xiàng)目
IDEA作為主流的Java開(kāi)發(fā)環(huán)境,通過(guò)集成Docker插件,能夠極大地簡(jiǎn)化從代碼編寫(xiě)到容器鏡像構(gòu)建、上傳及部署的整個(gè)流程,這篇文章主要介紹了如何用IDEA+Docker一鍵部署項(xiàng)目SpringBoot項(xiàng)目的相關(guān)資料,需要的朋友可以參考下2025-12-12
Spring負(fù)載均衡LoadBalancer使用詳解
這篇文章主要介紹了Spring負(fù)載均衡LoadBalancer使用詳解,Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客戶端負(fù)載均衡器, 用來(lái)替代Ribbon,Spring官方提供了兩種客戶端都可以使用loadbalancer,需要的朋友可以參考下2023-11-11
Java多線程之Semaphore實(shí)現(xiàn)信號(hào)燈
這篇文章主要給大家分享的是Java多線程之Semaphore實(shí)現(xiàn)信號(hào)燈的練習(xí),emaphore是計(jì)數(shù)信號(hào)量。Semaphore管理一系列許可證。每個(gè)acquire方法阻塞,直到有一個(gè)許可證可以獲得然后拿走一個(gè)許可證;下面一起進(jìn)入文章學(xué)習(xí)Semaphore的具體內(nèi)容2021-10-10
完整java開(kāi)發(fā)中JDBC連接數(shù)據(jù)庫(kù)代碼和步驟
這篇文章主要介紹了完整java開(kāi)發(fā)中JDBC連接數(shù)據(jù)庫(kù)代碼和步驟,需要的朋友可以參考下2015-09-09
javacv依賴(lài)太大導(dǎo)致jar包也大的解決辦法
隨著項(xiàng)目的復(fù)雜度和依賴(lài)關(guān)系的增加,打包后的JAR包可能會(huì)變得很大,這篇文章主要介紹了javacv依賴(lài)太大導(dǎo)致jar包也大的解決辦法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-09-09
springboot整合mybatis plus與druid詳情
這篇文章主要介紹了springboot整合mybatis plus與druid詳情,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的下伙伴可以參考一下2022-09-09

