MyBatis動態SQL進階:復雜查詢與性能優化實戰

引言

在復雜業務場景中,SQL查詢往往需要動態拼接條件、復用代碼片段,并支持批量操作。MyBatis的動態SQL功能提供了強大的解決方案,本文將深入解析<choose>條件分支、<sql>片段復用、批量操作優化等核心技巧,助你寫出高效、可維護的SQL映射。

一、條件分支:choose / when / otherwise標簽

1.1 場景說明

假設需要實現一個商品查詢接口,支持以下條件組合:

  • 按名稱模糊查詢
  • 按價格區間查詢
  • 按狀態精確查詢
  • 若無條件則返回所有商品

1.2 動態SQL實現

<select id="selectGoods" resultType="Goods">SELECT * FROM goods<where><choose><when test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</when><when test="minPrice != null and maxPrice != null">AND price BETWEEN #{minPrice} AND #{maxPrice}</when><when test="status != null">AND status = #{status}</when><otherwise>AND is_deleted = 0  <!-- 默認未刪除 --></otherwise></choose></where>
</select>

1.3 執行流程解析

  1. <choose>標簽內按順序匹配第一個滿足的<when>條件
  2. 若所有<when>均不滿足,則執行<otherwise>
  3. <where>標簽自動處理前綴AND/OR及空條件

二、SQL片段復用:sql標簽與include標簽

2.1 場景說明

多個查詢需要復用以下內容:

  • 基礎字段列表(id, name, price)
  • 公共過濾條件(未刪除)

2.2 定義與引用

<!-- 定義SQL片段 -->
<sql id="Base_Column_List">id, name, price, status, create_time
</sql><sql id="Common_Where">AND is_deleted = 0
</sql><!-- 引用片段 -->
<select id="selectGoodsList" resultType="Goods">SELECT <include refid="Base_Column_List"/>FROM goods<where><include refid="Common_Where"/><if test="categoryId != null">AND category_id = #{categoryId}</if></where>
</select>

2.3 進階用法:帶參數的SQL片段

<sql id="Price_Filter"><if test="minPrice != null">AND price >= #{minPrice}</if><if test="maxPrice != null">AND price <= #{maxPrice}</if>
</sql><!-- 使用時 -->
<select id="selectByPrice" resultType="Goods">SELECT * FROM goods<where><include refid="Common_Where"/><include refid="Price_Filter"/></where>
</select>

三、批量操作優化

3.1 批量插入優化

傳統單條插入(低效)
<insert id="insertGoods" parameterType="Goods">INSERT INTO goods (name, price) VALUES (#{name}, #{price})
</insert>

Java調用:

for (Goods goods : list) {goodsMapper.insertGoods(goods);
}
批量插入(高效)
<insert id="batchInsert" parameterType="java.util.List">INSERT INTO goods (name, price) VALUES<foreach collection="list" item="item" separator=",">(#{item.name}, #{item.price})</foreach>
</insert>

3.2 批量更新優化

<update id="batchUpdatePrice" parameterType="java.util.List"><foreach collection="list" item="item" separator=";">UPDATE goodsSET price = #{item.newPrice}WHERE id = #{item.id}</foreach>
</update>

3.3 性能關鍵配置

在JDBC URL中添加批處理參數:

jdbc.url=jdbc:mysql://localhost:3306/mydb?rewriteBatchedStatements=true

MyBatis全局配置啟用批量模式:

<settings><setting name="defaultExecutorType" value="BATCH"/>
</settings>

四、性能優化建議

  1. 減少動態SQL嵌套

    • 避免在<foreach>中嵌套其他動態標簽
    • 復雜邏輯優先在Java層處理
  2. 合理使用緩存

    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
    
  3. 批量操作最佳實踐

    try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {GoodsMapper mapper = session.getMapper(GoodsMapper.class);for (Goods goods : list) {mapper.update(goods);}session.commit();
    }
    

五、完整示例代碼

// GoodsMapper.java
public interface GoodsMapper {List<Goods> selectGoods(@Param("name") String name,@Param("minPrice") BigDecimal minPrice,@Param("maxPrice") BigDecimal maxPrice,@Param("status") Integer status);int batchInsert(@Param("list") List<Goods> goodsList);
}
<!-- GoodsMapper.xml -->
<mapper namespace="com.example.mapper.GoodsMapper"><sql id="Base_Column_List">id, name, price, status, create_time</sql><select id="selectGoods" resultType="Goods">SELECT <include refid="Base_Column_List"/>FROM goods<where><choose><when test="name != null">name LIKE CONCAT('%', #{name}, '%')</when><when test="minPrice != null and maxPrice != null">price BETWEEN #{minPrice} AND #{maxPrice}</when><otherwise>status = 1</otherwise></choose></where></select><insert id="batchInsert" parameterType="list">INSERT INTO goods (name, price) VALUES<foreach collection="list" item="item" separator=",">(#{item.name}, #{item.price})</foreach></insert>
</mapper>

六、總結

技術點適用場景性能影響最佳實踐
<choose>多條件分支選擇優先處理高頻條件
<sql>復用字段/條件復用避免過度抽象
批量插入大數據量寫入配合JDBC批處理參數
動態SQL緩存重復執行的動態查詢設置合理的flushInterval

通過靈活運用MyBatis的動態SQL特性,可顯著提升復雜查詢場景的開發效率和運行性能。實際開發中需根據數據量、查詢復雜度、并發量等因素綜合選擇優化策略。

mybatis基礎專欄就結束啦,期待下我下專欄mybatis進階,感情到一定階段了,可以深入了解一下了!🤔

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

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

相關文章

@Transactional 注解失效的場景及原因分析

先分析一下 1&#xff0c;內部調用&#xff0c;原對象調用&#xff0c;不是代理對象調用 2&#xff0c;private方法&#xff0c;源碼中&#xff0c;只能是public方法 3&#xff0c;異常被捕獲了&#xff0c;事物攔截器&#xff0c;無法感知 4&#xff0c;子線程調用&#x…

使用unity創建項目,進行動畫制作

1. 創建unity項目 error: error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/PlasticSCM/log4netPlastic.dll could not be found error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/Plasti…

Centos系統及國產麒麟系統設置自己寫的go服務的開機啟動項完整教程

1、創建服務文件 在 /etc/systemd/system/ 下新建服務配置文件&#xff08;需sudo權限&#xff09;&#xff0c;例如&#xff1a; sudo nano /etc/systemd/system/mygo.service 如下圖&#xff0c;創建的mygo.service 2、創建內容如下&#xff1a; DescriptionThe go HTTP a…

Java面試寶典: IO流

1. 下面哪個流類屬于面向字符的輸入流() 選項: A. BufferedWriter B. FileInputStream C. ObjectInputStream D. InputStreamReader 答案:D 詳細分析: 字符流與字節流的本質區別: 字符流(Character Streams)以Unicode字符為單位操作數據,適用于文本處理字節流(Byte…

黑馬python(二十五)

目錄&#xff1a;1.數據輸出-輸出為Python對象2.數據輸出-輸出到文件中3.綜合案例1.數據輸出-輸出為Python對象2.數據輸出-輸出到文件中移動文件到文件夾&#xff1a;生成了好多文件&#xff0c;因為Rdd是有分區的 &#xff0c;會把數據分散到各個分區去存儲&#xff0c;因為電…

【LeetCode 熱題 100】41. 缺失的第一個正數——(解法一)暴力解

Problem: 41. 缺失的第一個正數 題目&#xff1a;給你一個未排序的整數數組 nums &#xff0c;請你找出其中沒有出現的最小的正整數。 請你實現時間復雜度為 O(n) 并且只使用常數級別額外空間的解決方案。 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(N log N)…

在運行 Laravel Sail 前,需安裝 Docker Desktop 并完成基礎配置/具體步驟

一、安裝 Docker Desktop&#xff08;必備環境&#xff09; Windows 系統 &#xff08;windows安裝包 有兩個版本&#xff09; 架構版本查看 1. Win R? 輸入 ?cmd? 打開命令提示符&#xff1b; 2. ?輸入命令?&#xff1a; bash echo %PROCESSOR_ARCHITECTURE% 3. ?結果…

AI 應用于進攻性安全

一、引言 大語言模型&#xff08;LLM&#xff09;和 AI 智能體的出現推動進攻性安全變革&#xff0c;其在偵察、掃描、漏洞分析、利用、報告五個階段展現出數據分析、代碼生成、攻擊場景規劃等能力&#xff0c;能提升安全團隊效率與擴展性&#xff0c;但存在 “幻覺” 等局限性…

微控制器中的EXTI0(External Interrupt 0)中斷是什么?

微控制器中的EXTI0(External Interrupt 0)中斷是什么? EXTI0(External Interrupt 0) 是微控制器(如STM32等ARM Cortex-M系列芯片)中的一個外部中斷線,專門用于處理來自特定GPIO引腳的外部信號觸發中斷。以下是詳細說明: 1. 基本概念 EXTI(External Interrupt/Event …

EasyGBS平臺內置AI算法了,算法成為了視頻平臺的標配

今年五一的時候立了個flag&#xff08;《國標GB28181平臺EasyGBS未來研發方向在哪&#xff1f;》&#xff09;&#xff0c;我想不能再局限在只是滿足于傳統視頻平臺的功能&#xff0c;傳統的EasyGBS也就是接入幾種視頻協議&#xff0c;什么RTSP、ONVIF、RTMP、GB28181這些&…

C# 常量與變量

在 C# 中&#xff0c;常量和變量是存儲數據的基本方式&#xff1a; // 常量&#xff1a;使用 const 關鍵字聲明&#xff0c;必須在聲明時初始化&#xff0c;且值不能改變 const double Pi 3.14159; const string Message "Hello, World!"; ? // 變量&#xff1a;…

TensorRT-LLM:大模型推理加速的核心技術與實踐優勢

大型語言模型推理就像讓一頭300公斤的大熊貓玩平衡木——顯存消耗和計算效率這對雙胞胎問題隨時可能讓表演翻車。以主流的7B參數模型為例&#xff0c;FP16精度下僅模型權重就吃掉14GB顯存&#xff0c;這還沒算上推理過程中不斷膨脹的KV Cache——當處理2048長度的對話時&#x…

免費棱光 PDF:免安裝 加水印 去水印 批量格式轉換

各位辦公小能手們&#xff0c;今天給大家介紹一款超棒的PDF處理工具——棱光PDF&#xff01;它完全免費&#xff0c;專門解決咱對PDF文件的常見操作需求。綠色免安裝&#xff0c;體積小得跟顆花生米似的&#xff0c;打開就能用。它有三大核心功能&#xff0c;分別是水印管理、格…

(二)復習(Error Pattern/Result Pattern/)

文章目錄 項目地址一、Error Pattern1.1 定義Error類1. ErrorType 可發生的錯誤類型2. Error類3. ValidataionError1.2 給每個實體創建Error類1. CategoryError類2. TicketErrror類3. EventErrror類二、Result Pattern1.1 自定義返回Result1. 泛型類2. 泛型方法1.2 Api層的Resu…

20250705-day6

NATO&#xff1a;北大西洋公約組織 Software Crisis&#xff1a;軟件危機 Paradigm&#xff1a;設計范型 Waterfall Model&#xff1a;瀑布模型 Prototype Model&#xff1a;原型模型&#xff08;又稱快速模型&#xff09; Spiral Model&#xff1a;螺旋模型 Agile&#xff1a;…

視頻播放中時鐘的概念及音視頻同步概念

author: hjjdebug date: 2025年 07月 05日 星期六 18:20:45 CST descrip: 視頻播放中時鐘的概念及音視頻同步概念 文章目錄 1.前言: 視頻播放:1. 固定延時時間2. 根據frame的duration來延時.3. 根據frame的PTS 來播放3.1. 時鐘是什么?3.2. 時鐘的用途. 2.音視頻同步: 1.前言: …

Python基礎之字符串操作全解析

在 Python 中&#xff0c;字符串是最常用的數據類型之一&#xff0c;掌握字符串的各種操作對于日常編程至關重要。本文將詳細介紹 Python 字符串的類型特性、編碼轉換、常用運算符及方法&#xff0c;幫助你全面掌握字符串處理技巧。 一、字符串的基本類型 Python 中的字符串屬…

【爬蟲】逆向爬蟲初體驗之爬取音樂

尋找數據 打開F12中的網絡頁面&#xff0c;播放音樂后&#xff0c;篩選媒體&#xff0c;會發現當前這首歌曲音頻鏈接地址&#xff0c;打開后&#xff0c;點擊“標頭”就能能看到請求URL 截取“.mp3”前面的一部分進行搜索&#xff0c;搜索出來了很多數據包&#xff0c;但都是…

CppCon 2018 學習:Fancy Pointers for Fun and Profit

“Fancy Pointers for Fun and Profit” 這個標題聽起來像是在討論**“高級指針用法”**&#xff0c;尤其是在C里&#xff0c;如何利用智能指針、定制指針類型&#xff0c;或者其他高級指針技巧來寫更安全、更高效、更優雅的代碼。 可能的理解和內容方向&#xff1a; 1. 什么是…

思辨場域丨數字信號技術重塑農林牧漁:從“靠天吃飯”到“靠數吃飯”

凌晨三點&#xff0c;山東萊蕪的養豬戶老李被手機震動驚醒。屏幕顯示&#xff1a;3號豬舍&#xff0c;母豬即將分娩。他輕點屏幕啟動遠程監控&#xff0c;翻身繼續入睡——而在幾年前&#xff0c;這樣的夜晚他只能在豬圈里守著。 清晨的茶園里&#xff0c;興業縣的茶農王大姐掏…