MyBatis事務(wù)原理與實戰(zhàn)深入解析
MyBatis 事務(wù)深度解析:原理、配置與企業(yè)級實戰(zhàn)
事務(wù)是保證數(shù)據(jù)一致性的核心機制,尤其在多步數(shù)據(jù)庫操作場景中(如 “下單減庫存”“轉(zhuǎn)賬轉(zhuǎn)賬”),事務(wù)的 ACID 特性(原子性、一致性、隔離性、持久性)能避免出現(xiàn)數(shù)據(jù)臟讀、幻讀、部分成功等問題。MyBatis 作為持久層框架,本身不直接管理事務(wù),而是依賴底層數(shù)據(jù)源(如 JDBC)或整合 Spring 框架實現(xiàn)事務(wù)控制。本文將從事務(wù)核心概念出發(fā),深入拆解 MyBatis 事務(wù)的實現(xiàn)原理、兩種核心使用方式(原生 JDBC 事務(wù)、Spring 聲明式事務(wù))、隔離級別配置及企業(yè)級實戰(zhàn)場景,幫助開發(fā)者徹底掌握 MyBatis 事務(wù)的正確用法。
一、核心基礎(chǔ):MyBatis 事務(wù)的本質(zhì)與依賴
1. 事務(wù)的核心價值
在無事務(wù)控制的場景中,多步數(shù)據(jù)庫操作可能出現(xiàn) “部分成功” 的風(fēng)險。例如 “用戶下單” 流程需執(zhí)行兩步操作:① 插入訂單記錄;② 扣減商品庫存。若第一步成功、第二步失敗,會導(dǎo)致 “訂單已創(chuàng)建但庫存未扣減” 的臟數(shù)據(jù)。事務(wù)的核心價值就是通過 ACID 特性保證:多步操作 “要么全成功,要么全回滾”,確保數(shù)據(jù)一致性。
2. MyBatis 事務(wù)的底層依賴
MyBatis 本身不提供事務(wù)管理器,事務(wù)控制依賴以下兩種底層機制,核心是通過SqlSession控制數(shù)據(jù)庫連接的事務(wù)行為:
- JDBC 事務(wù):依賴 JDBC 的
Connection對象,通過setAutoCommit(false)關(guān)閉自動提交,commit()提交事務(wù),rollback()回滾事務(wù),適用于非 Spring 環(huán)境; - Spring 事務(wù):Spring 提供統(tǒng)一的事務(wù)管理器(
DataSourceTransactionManager),MyBatis 通過SqlSessionFactory與 Spring 事務(wù)管理器整合,支持聲明式事務(wù)(@Transactional注解),是企業(yè)級開發(fā)的主流方案。
3. MyBatis 事務(wù)的核心組件
- SqlSession:MyBatis 的核心會話對象,每個 SqlSession 綁定一個數(shù)據(jù)庫連接(
Connection),事務(wù)的提交 / 回滾本質(zhì)是通過 SqlSession 控制 Connection 的事務(wù)行為; - TransactionFactory:事務(wù)工廠,負責(zé)創(chuàng)建
Transaction對象,默認提供JdbcTransactionFactory(適配 JDBC 事務(wù))和ManagedTransactionFactory(適配容器管理事務(wù)); - Transaction:事務(wù)接口,封裝了事務(wù)的提交、回滾、關(guān)閉等操作,底層委托給 Connection 實現(xiàn);
- Executor:MyBatis 的執(zhí)行器,所有數(shù)據(jù)庫操作通過 Executor 執(zhí)行,Executor 會通過 Transaction 獲取數(shù)據(jù)庫連接,確保同一事務(wù)內(nèi)的操作使用同一個 Connection。
二、原生 JDBC 事務(wù):MyBatis 手動控制事務(wù)(非 Spring 環(huán)境)
在不使用 Spring 框架的場景中,MyBatis 通過原生 JDBC 事務(wù)實現(xiàn)手動控制,核心是通過SqlSession的commit()和rollback()方法管理事務(wù),底層依賴 JDBC 的 Connection 對象。
1. 核心原理
- MyBatis 默認開啟 “自動提交事務(wù)”(
autoCommit=true),即每個 SQL 語句獨立成為一個事務(wù),執(zhí)行后自動提交; - 手動控制事務(wù)時,需先通過
sqlSessionFactory.openSession(false)關(guān)閉自動提交,此時 SqlSession 綁定的 Connection 處于 “事務(wù)未提交” 狀態(tài); - 多步 SQL 操作執(zhí)行完成后,調(diào)用
sqlSession.commit()提交事務(wù);若執(zhí)行過程中拋出異常,調(diào)用sqlSession.rollback()回滾事務(wù); - 事務(wù)提交 / 回滾后,需關(guān)閉 SqlSession 釋放連接。
2. 實戰(zhàn)演示:原生 JDBC 事務(wù)手動控制
(1)環(huán)境準(zhǔn)備(非 Spring)
- 依賴配置(pom.xml):
<!-- MyBatis核心依賴 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
<!-- MySQL驅(qū)動 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 數(shù)據(jù)源(C3P0) -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>- MyBatis 配置文件(mybatis-config.xml):
<configuration>
<!-- 環(huán)境配置:配置事務(wù)工廠和數(shù)據(jù)源 -->
<environments default="development">
<environment id="development">
<!-- 事務(wù)工廠:使用JDBC事務(wù)工廠 -->
<transactionManager type="JDBC"/>
<!-- 數(shù)據(jù)源:C3P0連接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test_mybatis?useSSL=false&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="poolMaximumActiveConnections" value="10"/>
</dataSource>
</environment>
</environments>
<!-- 映射器掃描 -->
<mappers>
<mapper resource="mapper/OrderMapper.xml"/>
<mapper resource="mapper/ProductMapper.xml"/>
</mappers>
</configuration>(2)Mapper 接口與 XML(下單減庫存場景)
- OrderMapper.java(插入訂單):
public interface OrderMapper {
int insertOrder(Order order);
}
- ProductMapper.java(扣減庫存):
public interface ProductMapper {
int decreaseStock(@Param("productId") Long productId, @Param("num") Integer num);
}
- OrderMapper.xml:
<mapper namespace="com.example.mapper.OrderMapper">
<insert id="insertOrder" parameterType="com.example.entity.Order">
INSERT INTO `order`(order_no, product_id, num, create_time)
VALUES(#{orderNo}, #{productId}, #{num}, NOW())
</insert>
</mapper>- ProductMapper.xml:
<mapper namespace="com.example.mapper.ProductMapper">
<update id="decreaseStock">
UPDATE product SET stock = stock - #{num} WHERE id = #{productId} AND stock >= #{num}
</update>
</mapper>(3)手動控制事務(wù)代碼
public class TransactionDemo {
public static void main(String[] args) {
// 1. 加載MyBatis配置,創(chuàng)建SqlSessionFactory
String resource = "mybatis-config.xml";
try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 2. 開啟SqlSession,關(guān)閉自動提交(false表示手動控制事務(wù))
SqlSession sqlSession = sqlSessionFactory.openSession(false);
try {
// 3. 獲取Mapper接口
OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
ProductMapper productMapper = sqlSession.getMapper(ProductMapper.class);
// 4. 模擬下單流程:① 插入訂單;② 扣減庫存
Order order = new Order();
order.setOrderNo(UUID.randomUUID().toString());
order.setProductId(1L);
order.setNum(2);
orderMapper.insertOrder(order); // 第一步:插入訂單
int rows = productMapper.decreaseStock(1L, 2); // 第二步:扣減庫存
if (rows == 0) {
throw new RuntimeException("庫存不足,扣減失敗");
}
// 5. 所有操作成功,提交事務(wù)
sqlSession.commit();
System.out.println("事務(wù)提交成功:下單流程完成");
} catch (Exception e) {
// 6. 發(fā)生異常,回滾事務(wù)
sqlSession.rollback();
System.out.println("事務(wù)回滾:" + e.getMessage());
} finally {
// 7. 關(guān)閉SqlSession,釋放連接
sqlSession.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}3. 核心注意事項
- 必須通過
openSession(false)關(guān)閉自動提交,否則事務(wù)控制失效; - 同一事務(wù)內(nèi)的所有操作必須使用同一個 SqlSession(確保使用同一個數(shù)據(jù)庫連接);
- 異常捕獲后必須手動調(diào)用
rollback(),否則事務(wù)會一直處于未提交狀態(tài),導(dǎo)致連接泄露; - 事務(wù)提交 / 回滾后,SqlSession 不可重復(fù)使用,需重新創(chuàng)建。
三、Spring 聲明式事務(wù):MyBatis 企業(yè)級主流方案
在 Spring 框架中,MyBatis 與 Spring 事務(wù)管理器深度整合,支持聲明式事務(wù)(通過@Transactional注解),無需手動控制SqlSession的提交 / 回滾,簡化事務(wù)代碼,是企業(yè)級開發(fā)的首選方案。
1. 核心原理
- Spring 提供
DataSourceTransactionManager作為事務(wù)管理器,該管理器通過 MyBatis 的SqlSessionFactory獲取數(shù)據(jù)庫連接,統(tǒng)一管理事務(wù); - 當(dāng)方法添加
@Transactional注解后,Spring 會通過 AOP 動態(tài)生成代理對象,在方法執(zhí)行前開啟事務(wù)(關(guān)閉 Connection 自動提交),方法執(zhí)行成功后提交事務(wù),執(zhí)行失?。⊕伋霎惓#┖蠡貪L事務(wù); - Spring 事務(wù)管理器與 MyBatis 的
SqlSession無縫協(xié)同:同一事務(wù)內(nèi),Spring 會確保所有 MyBatis 操作使用同一個SqlSession(綁定同一個 Connection),保證事務(wù)原子性。
2. 實戰(zhàn)演示:Spring 聲明式事務(wù)整合 MyBatis
(1)環(huán)境準(zhǔn)備(Spring Boot + MyBatis)
- 依賴配置(pom.xml):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.10</version>
</parent>
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis + Spring Boot整合依賴 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<!-- MySQL驅(qū)動 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>- 配置文件(application.yml):
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_mybatis?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
# Spring事務(wù)配置(可選,默認已配置DataSourceTransactionManager)
transaction:
rollback-on-commit-failure: true # 提交失敗時回滾
mybatis:
mapper-locations: classpath:mapper/**/*.xml
type-aliases-package: com.example.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL,便于調(diào)試(2)Service 層添加 @Transactional 注解
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private ProductMapper productMapper;
/**
* 下單流程:插入訂單 + 扣減庫存
* @Transactional:聲明式事務(wù),默認 RuntimeException 觸發(fā)回滾
*/
@Transactional(
rollbackFor = Exception.class, // 所有異常都回滾(默認僅RuntimeException回滾)
propagation = Propagation.REQUIRED, // 事務(wù)傳播行為:默認,當(dāng)前無事務(wù)則創(chuàng)建新事務(wù)
isolation = Isolation.DEFAULT // 隔離級別:默認,使用數(shù)據(jù)庫默認隔離級別
)
public void createOrder(Order order) {
// 1. 插入訂單
orderMapper.insertOrder(order);
// 2. 扣減庫存
int rows = productMapper.decreaseStock(order.getProductId(), order.getNum());
if (rows == 0) {
throw new RuntimeException("庫存不足,下單失敗");
}
// 3. 模擬其他業(yè)務(wù)操作(如記錄日志)
System.out.println("下單成功,訂單號:" + order.getOrderNo());
}
}(3)Controller 層測試
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping
public ResponseEntity<String> createOrder(@RequestBody Order order) {
try {
order.setOrderNo(UUID.randomUUID().toString());
orderService.createOrder(order);
return ResponseEntity.ok("下單成功");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("下單失?。? + e.getMessage());
}
}
}3. @Transactional 注解核心配置參數(shù)
@Transactional注解提供豐富的配置參數(shù),可根據(jù)業(yè)務(wù)需求調(diào)整事務(wù)行為,核心參數(shù)如下:
| 參數(shù)名 | 作用說明 | 可選值 |
|---|---|---|
rollbackFor | 指定觸發(fā)回滾的異常類型(默認僅 RuntimeException 及其子類回滾) | 如Exception.class(所有異?;貪L)、SQLException.class(特定異?;貪L) |
noRollbackFor | 指定不觸發(fā)回滾的異常類型 | 如BusinessException.class(業(yè)務(wù)異常不回滾) |
propagation | 事務(wù)傳播行為(多事務(wù)方法嵌套時的行為) | REQUIRED(默認)、SUPPORTS、REQUIRES_NEW、NESTED 等 |
isolation | 事務(wù)隔離級別(解決臟讀、不可重復(fù)讀、幻讀問題) | DEFAULT(默認,數(shù)據(jù)庫隔離級別)、READ_UNCOMMITTED、READ_COMMITTED 等 |
timeout | 事務(wù)超時時間(秒),超過時間未完成則自動回滾 | 如30(30 秒超時) |
readOnly | 是否為只讀事務(wù)(僅查詢操作,設(shè)置為 true 可優(yōu)化性能,不可執(zhí)行增刪改) | true/false(默認 false) |
關(guān)鍵參數(shù)詳解:
- 事務(wù)傳播行為:最常用
REQUIRED(當(dāng)前無事務(wù)則創(chuàng)建新事務(wù),有事務(wù)則加入當(dāng)前事務(wù))和REQUIRES_NEW(無論當(dāng)前是否有事務(wù),都創(chuàng)建新事務(wù)); - 事務(wù)隔離級別:企業(yè)級常用
READ_COMMITTED(避免臟讀,大多數(shù)數(shù)據(jù)庫默認級別),SERIALIZABLE(最高隔離級別,避免所有并發(fā)問題,但性能最低); - readOnly:純查詢方法建議設(shè)置
readOnly=true,Spring 會優(yōu)化事務(wù)配置(如關(guān)閉寫操作權(quán)限),提升查詢性能。
四、MyBatis 事務(wù)常見問題與解決方案
1. 事務(wù)不生效問題(高頻問題)
問題現(xiàn)象:
@Transactional注解添加后,事務(wù)未生效(部分操作成功、部分失敗時未回滾)。
常見原因與解決方案:
- 原因 1:方法非 public 修飾:Spring AOP 僅對 public 方法生成代理,非 public 方法的
@Transactional注解無效;解決方案:確保事務(wù)方法為 public 修飾; - 原因 2:異常被 catch 捕獲未拋出:Spring 事務(wù)僅在方法拋出指定異常時才回滾,若異常被 try-catch 捕獲且未重新拋出,事務(wù)不會回滾;解決方案:捕獲異常后手動拋出(如
throw new RuntimeException(e)),或使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()手動觸發(fā)回滾; - 原因 3:數(shù)據(jù)源未被 Spring 管理:MyBatis 的 SqlSessionFactory 未使用 Spring 的數(shù)據(jù)源,導(dǎo)致 Spring 事務(wù)管理器無法控制連接;解決方案:確保數(shù)據(jù)源通過
spring.datasource配置,由 Spring 自動注入; - 原因 4:內(nèi)部方法調(diào)用:同一類中無事務(wù)方法調(diào)用有事務(wù)方法,AOP 無法攔截,事務(wù)無效;解決方案:將事務(wù)方法抽取到其他 Service 類,或通過
AopContext.currentProxy()獲取代理對象調(diào)用。
2. 事務(wù)并發(fā)問題(臟讀、不可重復(fù)讀、幻讀)
問題說明:
多線程并發(fā)操作同一數(shù)據(jù)時,可能出現(xiàn)以下問題:
- 臟讀:一個事務(wù)讀取到另一個事務(wù)未提交的數(shù)據(jù);
- 不可重復(fù)讀:同一事務(wù)內(nèi)多次查詢同一數(shù)據(jù),結(jié)果不一致;
- 幻讀:同一事務(wù)內(nèi)多次查詢,結(jié)果集行數(shù)不一致。
解決方案:
- 調(diào)整事務(wù)隔離級別:如設(shè)置
isolation = Isolation.READ_COMMITTED(避免臟讀)、Isolation.REPEATABLE_READ(避免臟讀和不可重復(fù)讀); - 加鎖:通過數(shù)據(jù)庫鎖(如行鎖、表鎖)或分布式鎖(Redis/ZooKeeper)控制并發(fā)訪問;
- 避免長事務(wù):長事務(wù)會占用數(shù)據(jù)庫連接,增加并發(fā)沖突概率,盡量拆分長事務(wù)為短事務(wù)。
3. 事務(wù)提交失敗問題
問題現(xiàn)象:
方法執(zhí)行無異常,但事務(wù)提交失?。〝?shù)據(jù)未入庫)。
常見原因與解決方案:
- 原因 1:數(shù)據(jù)庫引擎不支持事務(wù):如 MySQL 的 MyISAM 引擎不支持事務(wù),InnoDB 引擎支持;解決方案:將數(shù)據(jù)庫表引擎改為 InnoDB;
- 原因 2:事務(wù)超時:事務(wù)執(zhí)行時間超過
timeout配置,被 Spring 自動回滾;解決方案:優(yōu)化 SQL 執(zhí)行效率,或適當(dāng)增大timeout值; - 原因 3:連接池參數(shù)不合理:連接池最大連接數(shù)不足,導(dǎo)致事務(wù)無法獲取連接提交;解決方案:調(diào)整連接池參數(shù)(如
spring.datasource.hikari.max-active)。
五、企業(yè)級實戰(zhàn):MyBatis 事務(wù)最佳實踐
1. 分層事務(wù)控制原則
- 事務(wù)應(yīng)添加在 Service 層:Service 層負責(zé)業(yè)務(wù)邏輯整合,多步數(shù)據(jù)庫操作的事務(wù)控制應(yīng)在 Service 層統(tǒng)一管理,避免在 Controller 或 Mapper 層添加事務(wù);
- 粒度適中:事務(wù)粒度不宜過大(避免長事務(wù)),也不宜過?。ū苊馐聞?wù)碎片化),以 “一個完整業(yè)務(wù)場景” 為單位(如 “下單”“轉(zhuǎn)賬”)。
2. 高頻場景事務(wù)配置示例
(1)純查詢方法(只讀事務(wù))
// 純查詢方法,設(shè)置readOnly=true優(yōu)化性能
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public List<Order> getOrderByUserId(Long userId) {
return orderMapper.selectByUserId(userId);
}(2)轉(zhuǎn)賬業(yè)務(wù)(高一致性要求)
// 轉(zhuǎn)賬業(yè)務(wù):扣減付款方余額 + 增加收款方余額,要求強一致性
@Transactional(
rollbackFor = Exception.class,
isolation = Isolation.READ_COMMITTED,
timeout = 30
)
public void transfer(Long fromUserId, Long toUserId, BigDecimal amount) {
// 扣減付款方余額
userAccountMapper.decreaseBalance(fromUserId, amount);
// 增加收款方余額
userAccountMapper.increaseBalance(toUserId, amount);
}(3)嵌套事務(wù)(REQUIRES_NEW)
// 主事務(wù):創(chuàng)建訂單
@Transactional(rollbackFor = Exception.class)
public void createOrder(Order order) {
orderMapper.insertOrder(order);
// 調(diào)用子事務(wù)方法(創(chuàng)建訂單日志,獨立事務(wù),即使失敗不影響主事務(wù))
logService.recordOrderLog(order.getId());
}
// 子事務(wù):記錄訂單日志(獨立事務(wù))
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void recordOrderLog(Long orderId) {
OrderLog log = new OrderLog();
log.setOrderId(orderId);
log.setOperateTime(LocalDateTime.now());
orderLogMapper.insert(log);
}3. 事務(wù)監(jiān)控與排查技巧
- 開啟 Spring 事務(wù)日志:在 application.yml 中配置
logging.level.org.springframework.transaction=DEBUG,可查看事務(wù)開啟、提交、回滾的詳細日志; - 打印 SQL 執(zhí)行日志:MyBatis 配置
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl,查看 SQL 執(zhí)行順序和參數(shù); - 數(shù)據(jù)庫事務(wù)日志:如 MySQL 的 binlog 日志,可排查事務(wù)提交是否寫入數(shù)據(jù)庫。
六、總結(jié)
MyBatis 事務(wù)的核心是 “通過 SqlSession 控制數(shù)據(jù)庫連接的事務(wù)行為”,底層依賴 JDBC 事務(wù)機制,企業(yè)級開發(fā)中主要與 Spring 聲明式事務(wù)整合,通過@Transactional注解簡化事務(wù)控制。掌握 MyBatis 事務(wù)的關(guān)鍵在于:
- 理解事務(wù)的 ACID 特性,明確事務(wù)的適用場景(多步數(shù)據(jù)庫操作需保證一致性);
- 區(qū)分原生 JDBC 事務(wù)和 Spring 聲明式事務(wù)的使用場景(非 Spring 環(huán)境用原生,Spring 環(huán)境用聲明式);
- 熟練配置
@Transactional注解的核心參數(shù)(尤其是rollbackFor、propagation、isolation); - 規(guī)避常見問題(如事務(wù)不生效、并發(fā)沖突、提交失敗),遵循分層事務(wù)控制原則。
在實際開發(fā)中,應(yīng)根據(jù)業(yè)務(wù)場景選擇合適的事務(wù)策略:簡單場景用 Spring 默認配置,高一致性場景調(diào)整隔離級別和傳播行為,并發(fā)場景結(jié)合鎖機制,確保數(shù)據(jù)一致性和系統(tǒng)性能的平衡。
到此這篇關(guān)于MyBatis事務(wù)原理與實戰(zhàn)深入解析的文章就介紹到這了,更多相關(guān)MyBatis事務(wù)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot集成Access?DB實現(xiàn)數(shù)據(jù)導(dǎo)入和解析
microsoft?office?access是由微軟發(fā)布的關(guān)聯(lián)式數(shù)據(jù)庫管理系統(tǒng),它結(jié)合了?microsoft?jet?database?engine?和?圖形用戶界面兩項特點,是一種關(guān)系數(shù)據(jù)庫工具,本文給大家介紹了SpringBoot集成Access?DB實現(xiàn)數(shù)據(jù)導(dǎo)入和解析,需要的朋友可以參考下2024-11-11
Spring Boot 從靜態(tài)json文件中讀取數(shù)據(jù)所需字段
本文重點給大家介紹Spring Boot 從靜態(tài)json文件中讀取數(shù)據(jù)所需字段,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
java web用servlet監(jiān)聽器實現(xiàn)顯示在線人數(shù)
這篇文章主要為大家詳細介紹了java web用servlet監(jiān)聽器實現(xiàn)顯示在線人數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-03-03

