如何在 Spring Boot 項目中使用 MyBatis 進行批量操作以提升性能?

MyBatis 提供了 ExecutorType.BATCH 類型,允許將多個 SQL 語句進行組合,最后統一執行,從而減少數據庫的訪問頻率,提升性能。

以下是如何在 Spring Boot 項目中使用 MyBatis 進行批量操作的關鍵點:

1. 配置 MyBatis 使用 ExecutorType.BATCH

主要有兩種方式可以來配置 MyBatis 使用 BATCH 執行器類型:

a) 在 SqlSessionFactoryBean 中配置 (推薦在 Spring Boot 中使用):

在 Spring Boot 應用中,通常通過 SqlSessionFactoryBean 來配置 SqlSessionFactory。我們可以在 SqlSessionFactoryBean 中設置 defaultExecutorType 屬性為 BATCH

import org.apache.ibatis.session.ExecutorType;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration
public class MyBatisConfig {@Beanpublic SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);// 設置默認的 ExecutorType 為 BATCHorg.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();configuration.setDefaultExecutorType(ExecutorType.BATCH);factoryBean.setConfiguration(configuration);// ... 其他配置,例如 Mapper 掃描路徑等return factoryBean;}
}

b) 編程式的方式創建 SqlSession 時指定 ExecutorType.BATCH:

如果需要更細粒度的控制,或者只想在特定的操作中使用批量處理,可以在創建 SqlSession 時指定 ExecutorType.BATCH

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class UserService {@Autowiredprivate SqlSessionFactory sqlSessionFactory;@Autowiredprivate UserMapper userMapper;@Transactionalpublic void batchInsertUsers(List<User> users) {try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {UserMapper batchMapper = sqlSession.getMapper(UserMapper.class);for (User user : users) {batchMapper.insertUser(user); // 執行插入操作}sqlSession.flushStatements(); // 刷新批處理語句,執行批量操作sqlSession.commit(); // 提交事務}}
}

2. 在 Mapper XML 文件中編寫批量操作 SQL

在 Mapper XML 文件中,需要編寫能夠處理集合參數的 SQL 語句,通常使用 <foreach> 標簽來循環遍歷集合并構建批量 SQL。

a) 批量 INSERT 示例:

假設有一個 User 實體類,你需要批量插入多個用戶。

<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><insert id="batchInsertUsers" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">insert into users (username, password, email) values<foreach collection="list" item="item" separator=",">(#{item.username}, #{item.password}, #{item.email})</foreach></insert><insert id="insertUser" parameterType="com.example.entity.User" useGeneratedKeys="true" keyProperty="id">insert into users (username, password, email) values (#{username}, #{password}, #{email})</insert><!-- ... 其他 Mapper 方法 --></mapper>
  • parameterType="java.util.List": 指定方法參數類型為 List
  • <foreach collection="list" item="item" separator="," >: 循環遍歷傳入的 Listitem 代表當前循環的元素,separator 指定元素之間的分隔符為逗號 ,
  • (#{item.username}, #{item.password}, #{item.email}): 使用 #{item.propertyName} 獲取 User 對象的屬性值。
  • useGeneratedKeys="true" keyProperty="id": 如果需要獲取自增主鍵,需要配置 useGeneratedKeyskeyProperty

b) 批量 UPDATE 示例:

批量更新多個用戶的郵箱地址。

<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper"><update id="batchUpdateUsersEmail" parameterType="java.util.List"><foreach collection="list" item="item" separator=";" open="" close=";" index="index">update users set email = #{item.email} where id = #{item.id}</foreach></update><!-- ... 其他 Mapper 方法 --></mapper>
  • <foreach collection="list" item="item" separator=";" open="" close=";" index="index">: 循環遍歷 Listseparator=";" 使用分號作為分隔符。注意: 這里使用了分號 ; 分隔多個 UPDATE 語句。不同的數據庫對批量 UPDATE 的語法支持可能有所不同,有些數據庫可能不支持這種方式,或者有其他更高效的批量更新語法。例如 MySQL 可以使用 INSERT ... ON DUPLICATE KEY UPDATEREPLACE INTO 等。

3. Spring Boot Service 層調用批量操作 Mapper 方法

在 Spring Boot Service 層,需要調用 Mapper 接口中定義的批量操作方法,并傳入包含數據的 List務必使用 @Transactional 注解來管理事務,確保批量操作的原子性

import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic void batchInsertUsers(List<User> users) {userMapper.batchInsertUsers(users);}@Transactionalpublic void batchUpdateUsersEmail(List<User> users) {userMapper.batchUpdateUsersEmail(users);}
}

4. 性能優化的關注點

  • 事務管理 (@Transactional): 批量操作必須在事務中進行,以保證操作的原子性。如果批量操作過程中出現錯誤,可以回滾所有操作,保持數據一致性。Spring Boot 的 @Transactional 注解可以方便地管理事務。

  • 批量大小 (Batch Size): 批量操作并非批量越大越好。過大的批量可能會導致:

    • 數據庫壓力過大: 單次請求發送大量 SQL 可能導致數據庫服務器資源消耗過高。
    • 內存占用過高: 如果批量操作涉及到大量數據,可能會占用大量內存。
    • 事務時間過長: 過長的事務會增加鎖沖突的風險,影響并發性能。

    最佳批量大小需要根據實際場景進行測試和調優。一般來說,可以嘗試從較小的批量大小開始(例如 100, 500, 1000),逐步增加并監控數據庫性能,找到最佳的平衡點。

  • 數據庫連接池配置: 確保數據庫連接池配置合理,能夠支持高并發的批量操作。Spring Boot 默認使用 HikariCP 連接池,性能良好,但仍需根據應用負載調整連接池參數,例如 maximum-pool-size, minimum-idle 等。

  • 網絡延遲: 批量操作的主要優勢是減少網絡 round trips。如果網絡延遲較高,批量操作的性能提升會更加明顯。

  • 數據庫服務器性能: 最終性能也受限于數據庫服務器的性能。確保數據庫服務器配置合理,性能良好,例如 CPU, 內存, 磁盤 IO 等。

  • 批量操作的適用場景: 批量操作最適合一次性處理大量數據的場景,例如數據導入、數據遷移、批量更新狀態等。對于頻繁的小批量操作,可能提升效果不明顯,甚至可能因為額外的批處理開銷而降低性能。

  • Generated Keys 的處理: 如果批量 INSERT 需要獲取自增主鍵,MyBatis 提供了 useGeneratedKeyskeyProperty 屬性。但需要注意,不同數據庫對批量獲取自增主鍵的支持程度可能有所不同。對于 MySQL,批量 INSERT 可以一次性獲取所有自增主鍵。

  • 錯誤處理: 批量操作中如果某條 SQL 執行失敗,需要妥善處理錯誤。默認情況下,MyBatis 的 ExecutorType.BATCH 在遇到錯誤時會停止執行后續的 SQL。我們需要根據業務需求,決定是忽略錯誤繼續執行,還是回滾整個批量操作。

總結:

在 Spring Boot 項目中使用 MyBatis 的 ExecutorType.BATCH 進行批量操作,可以顯著提升處理大量數據的性能。關鍵在于正確配置 ExecutorType.BATCH,編寫高效的批量 SQL 語句,合理設置批量大小,并結合事務管理和錯誤處理機制。 性能優化是一個迭代過程,需要根據實際應用場景和性能測試結果進行調整和完善。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75430.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75430.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75430.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Redis 字符串(String)詳解

1. 什么是字符串類型 在 Redis 中&#xff0c;字符串&#xff08;String&#xff09; 是最基本的數據類型。它可以包含任何數據&#xff0c;比如文本、JSON、甚至二進制數據&#xff08;如圖片的 Base64 編碼&#xff09;&#xff0c;最大長度為 512 MB。 字符串在 Redis 中不…

Elasticsearch 系列專題 - 第四篇:聚合分析

聚合(Aggregation)是 Elasticsearch 的強大功能之一,允許你對數據進行分組、統計和分析。本篇將從基礎到高級逐步講解聚合的使用,并結合實際案例展示其應用。 1. 聚合基礎 1.1 什么是聚合(Aggregation)? 聚合是對文檔集合的統計分析,類似于 SQL 中的 GROUP BY 和聚合…

YOLO學習筆記 | YOLOv8 全流程訓練步驟詳解(2025年4月更新)

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 這里寫自定義目錄標題 一、數據準備1. 數據標注與格式轉換2. 配置文件生…

context上下文(一)

創建一個基礎的context 使用BackGround函數&#xff0c;BackGround函數原型如下&#xff1a; func Background() Context {return backgroundCtx{} } 作用&#xff1a;Background 函數用于創建一個空的 context.Context 對象。 context.Background() 函數用于獲取一個空的 cont…

Java中常見的設計模式

Java中常見的設計模式 Java 中有 23 種經典設計模式&#xff0c;通常被分為三大類&#xff1a;創建型、結構型和行為型。每個設計模式都解決了不同類型的設計問題。以下是幾種常見設計模式的總結&#xff0c;并附帶了實際應用場景、示例代碼和詳細的注釋說明。 一、創建型設計…

責任鏈設計模式(單例+多例)

目錄 1. 單例責任鏈 2. 多例責任鏈 核心區別對比 實際應用場景 單例實現 多例實現 初始化 初始化責任鏈 執行測試方法 歡迎關注我的博客&#xff01;26屆java選手&#xff0c;一起加油&#x1f498;&#x1f4a6;&#x1f468;?&#x1f393;&#x1f604;&#x1f602; 最近在…

springboot 處理編碼的格式為opus的音頻數據解決方案【java8】

opus編碼的格式概念&#xff1a; Opus是一個有損聲音編碼的格式&#xff0c;由Xiph.Org基金會開發&#xff0c;之后由IETF&#xff08;互聯網工程任務組&#xff09;進行標準化&#xff0c;目標是希望用單一格式包含聲音和語音&#xff0c;取代Speex和Vorbis&#xff0c;且適用…

vue項目引入tailwindcss

vue3項目引入tailwindcss vue3 vite tailwindcss3 版本 初始化項目 npm create vitelatest --template vue cd vue npm install npm run dev安裝tailwindcss3 和 postcss 引入 npm install -D tailwindcss3 postcss autoprefixer // 初始化引用 npx tailwindcss init -p…

Google ADK(Agent Development Kit)簡要示例說明

一、環境準備與依賴安裝 1.1 系統 硬件&#xff1a; GPU NVIDIA 3070加速模型推理&#xff0c;內存64GB軟件&#xff1a; Python 3.11Docker 28.04&#xff08;用于容器化部署&#xff09;Kubernetes 1.25&#xff08;可選&#xff0c;用于集群管理&#xff09; 1.2 安裝 A…

批量給文件編排序號,支持數字序號及時間日期序號編排文件

當我們需要對文件進行編號的時候&#xff0c;我們可以通過這個工具來幫我們完成&#xff0c;它可以支持從 001 到 100 甚至更多的數字序號編號。也可以支持按照日期、時間等方式對文件進行編號操作。這是一種操作簡單&#xff0c;處理起來也非常的高效文件編排序號的方法。 工作…

【系統架構】AI時代下,系統架構師如何修煉

在AI時代,系統架構師的角色正經歷深刻變革,需在技術深度、工具應用與思維模式上全面升級。以下結合行業趨勢與實踐建議,總結系統架構師的修煉路徑: 一、掌握AI工具,重構工作流 自動化文檔與設計 利用生成式AI(如DeepSeek、ChatGPT)完成70%的需求文檔、接口設計及架構圖生…

圖像顏色空間對比(Opencv)

1. 顏色轉換 import cv2 import matplotlib.pyplot as plotimg cv2.imread("tmp.jpg") img_r cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img_g cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img_h cv2.cvtColor(img, cv2.COLOR_BGR2HSV) img_l cv2.cvtColor(img, cv2.C…

JDBC驅動autosave缺陷的修復與配置指南

opengauss-jdbc-6.0.0.jar和opengauss-jdbc-6.0.0-og.jar版本修復了&#xff1a;autosavealways時&#xff0c;事務嵌套太深&#xff0c;導致棧溢出問題。如果使用的版本低于opengauss-jdbc-6.0.0版本&#xff0c;需要通過替換jdbc驅動和修改url參數來解決autosave缺陷。以下是…

K8S-證書過期更新

K8S證書過期問題 K8S證書過期處理方法 Unable to connect to the server: x509: certificate has expired or is not yet valid 1、查看證書有效期&#xff1a; # kubeadm certs check-expiration2、備份證書 # cp -rp /etc/kubernetes /etc/kubernetes.bak3、直接重建證書 …

2025 年網絡安全終極指南

我們生活在一個科技已成為日常生活不可分割的一部分的時代。對數字世界的依賴性日益增強的也帶來了更大的網絡風險。 網絡安全并不是IT專家的專屬特權&#xff0c;而是所有用戶的共同責任。通過簡單的行動&#xff0c;我們可以保護我們的數據、隱私和財務&#xff0c;降低成為…

Python的那些事第四十九篇:基于Python的智能客服系統設計與實現

基于Python的智能客服系統設計與實現 摘要 隨著人工智能技術的飛速發展,智能客服系統逐漸成為企業提升客戶服務質量和效率的關鍵工具。本文詳細介紹了基于Python的智能客服系統的設計與實現方案,涵蓋了系統架構、核心功能、技術選型及優化建議,旨在為企業構建高效、智能的客…

第Y1周:調用YOLOv5官方權重進行檢測

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 文章目錄 1、前言2、下載源碼3、運行代碼 1、前言 YOLOv5分為YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四個版本&#xff0c;這里以YOLOv5s為例。 2、下載源碼 安…

Python小程序 - 文件處理3:正則表達式

正則表達式&#xff1a;文本年鑒表。遺留的問題很多。。。用AI再想想 需求&#xff1a;讀入txt文件&#xff0c;過濾文件有關年記錄 0&#xff09;讀入txt文件 1&#xff09;以“。”&#xff0c;中文句號&#xff0c;為界區分一句&#xff0c;最小統計單位 2&#xff09;年格…

【antd + vue】Tree 樹形控件:默認展開所有樹節點 、點擊文字可以“選中/取消選中”節點

一、defaultExpandAll 默認展開所有樹節點 1、需求&#xff1a;默認展開所有樹節點 2、問題&#xff1a; v-if"data.length"判斷的層級不夠&#xff0c;只判斷到了物理那一層&#xff0c;所以只展開到那一層。 3、原因分析&#xff1a; 默認展開所有樹節點, 如果是…

Notepad++安裝Markdown實時預覽插件

具體操作 打開notepad -> 插件 -> 插件管理 -> 可用 -> “Markdown Panel” -> 安裝&#xff0c;安裝完成后工具欄點擊"Markdown Panel"按鈕。 注意&#xff1a;由于網絡等原因可能安裝失敗 導致工具欄沒出現""Markdown Panel"按鈕&am…