最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis 中動態(tài) SQL 的作用及執(zhí)行原理解析

 更新時間:2026年02月26日 15:43:04   作者:莫寒清  
MyBatis動態(tài)SQL通過一組XML標(biāo)簽實現(xiàn)多條件查詢、批量操作和按需更新等復(fù)雜場景,提升可讀性和可維護性,并配合#{}防止SQL注入,下面通過本文給大家介紹MyBatis 中動態(tài) SQL 的作用及執(zhí)行原理解析,感興趣的朋友跟隨小編一起看看吧

一句話總結(jié)

MyBatis 動態(tài) SQL 用一組 XML 標(biāo)簽(<if>、<choose>、<foreach>、<where>、<set> 等)在 Mapper 層按條件動態(tài)拼接 SQL,避免在 Java 代碼里手動拼接字符串,實現(xiàn)多條件查詢、批量操作和按需更新等復(fù)雜場景,提升可讀性與可維護性,并配合 #{} 保證安全。

一、動態(tài) SQL 的核心作用

1. 靈活的條件查詢(多條件拼接WHERE)

根據(jù)參數(shù)是否為空,按需拼接 WHERE 條件,避免大量 if 拼接 SQL 字符串,以及多余的 AND / OR。

<select id="findUser" resultType="User">
  SELECT * FROM user
  <where>
    <if test="name != null">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>
  • name、age 都為空時:只生成 SELECT * FROM user
  • 只有 name 不為空:生成 SELECT * FROM user WHERE name = ?

面試點:動態(tài) SQL 最典型用途之一就是多條件查詢,根據(jù)參數(shù)是否為空動態(tài)增加 WHERE 條件。

2. 減少重復(fù)代碼(替代多層 if-else 分支)

使用 <choose> / <when> / <otherwise> 做互斥分支選擇,避免同一個 SQL 寫多份、或者在 Java 里寫一堆 if-else。

<select id="findUserByType" resultType="User">
  SELECT * FROM user
  WHERE role =
  <choose>
    <when test="role == 'admin'">
      'ADMIN'
    </when>
    <when test="role == 'user'">
      'USER'
    </when>
    <otherwise>
      'GUEST'
    </otherwise>
  </choose>
</select>
  • 優(yōu)勢
    • XML 中邏輯集中統(tǒng)一、互斥關(guān)系清晰;
    • 減少重復(fù) SQL 片段,維護方便。

3. 動態(tài)批量操作(IN條件、批量插入 / 更新)

通過 <foreach> 遍歷集合,動態(tài)生成 IN (...) 或批量插入的 VALUES (...) 列表。

<select id="selectByIds" resultType="User">
  SELECT * FROM user WHERE id IN
  <foreach collection="ids"
           item="id"
           open="("
           separator=","
           close=")">
    #{id}
  </foreach>
</select>
  • 典型場景:批量查詢、批量更新、批量刪除等,減少數(shù)據(jù)庫往返次數(shù)、提升性能。

4. 配合參數(shù)綁定,降低 SQL 注入風(fēng)險

通過 #{} 占位符和 <bind> 動態(tài)生成參數(shù)值,防止將用戶輸入直接拼到 SQL 里。

<select id="findByNameLike" resultType="User">
  <bind name="pattern" value="'%' + name + '%'" />
  SELECT * FROM user
  WHERE name LIKE #{pattern}
</select>
  • 即使參數(shù)中包含 ' OR 1=1 --,也會被當(dāng)成普通字符串,而不是 SQL 片段執(zhí)行。
  • 注意:真正防注入的關(guān)鍵在于 #{} + 預(yù)編譯,動態(tài) SQL 只是避免你再去拼字符串。

5. 動態(tài)更新與字段控制(按需更新非空字段)

使用 <set> 標(biāo)簽只更新非空字段,并自動處理多余逗號。

<update id="updateUser">
  UPDATE user
  <set>
    <if test="name != null">
      name = #{name},
    </if>
    <if test="age != null">
      age = #{age},
    </if>
  </set>
  WHERE id = #{id}
</update>
  • 只會更新有值的字段,避免把字段更新成 NULL;
  • <set> 會自動去掉最后一個逗號,生成合法 SQL。

二、典型應(yīng)用場景(面試可以照著說)

場景動態(tài) SQL 標(biāo)簽組合效果
多條件查詢<if> + <where>按需生成 WHERE 子句,避免冗余條件
分頁 + 條件查詢<if> + <where> + 分頁插件條件 + 分頁統(tǒng)一在一個 Mapper 中維護
批量插入 / 更新<foreach>單條 SQL 處理多條數(shù)據(jù),減少數(shù)據(jù)庫交互
多表關(guān)聯(lián)查詢<choose> 動態(tài)選表 / 關(guān)聯(lián)根據(jù)業(yè)務(wù)條件選擇不同的關(guān)聯(lián)方式或表
動態(tài)排序<if> 控制 ORDER BY支持前端傳入排序字段、排序方式,實現(xiàn)靈活排序

一句話記憶:動態(tài) SQL 常用在多條件查詢、批量操作、動態(tài)排序、部分字段更新、復(fù)雜關(guān)聯(lián)這幾類場景。

三、動態(tài) SQL 的執(zhí)行原理(加分項)

  • OGNL 表達式解析
    • MyBatis 使用 OGNL(Object-Graph Navigation Language)解析 <if test="...">、<foreach> 等標(biāo)簽中的條件表達式;
    • 通過 test="name != null and name != ''" 這類表達式判斷是否拼接對應(yīng)的 SQL 片段。
  • SqlNode 組合成 SqlSource
    • 所有動態(tài)標(biāo)簽先被解析成一棵 SqlNode 樹(比如 IfSqlNode、WhereSqlNode 等);
    • 運行時根據(jù)入?yún)⒃谶@棵樹上“走一遍”,把滿足條件的節(jié)點拼接成完整 SQL,生成 SqlSource。
  • 預(yù)編譯與參數(shù)綁定
    • 最終 SQL 仍然通過 PreparedStatement 預(yù)編譯;
    • #{} 會變成 ? 占位符,參數(shù)通過 JDBC 安全綁定,既防注入又可復(fù)用執(zhí)行計劃。

四、實際場景示例:多條件搜索用戶

<select id="searchUsers" resultType="User">
  SELECT * FROM user
  <where>
    <if test="name != null and name != ''">
      AND name LIKE CONCAT('%', #{name}, '%')
    </if>
    <if test="minAge != null">
      AND age >= #{minAge}
    </if>
    <if test="roles != null and roles.size() > 0">
      AND role IN
      <foreach collection="roles"
               item="role"
               open="("
               close=")"
               separator=",">
        #{role}
      </foreach>
    </if>
  </where>
  ORDER BY create_time DESC
</select>
  • 支持:模糊查詢、年齡下限過濾、角色集合過濾;
  • 傳哪個條件就拼哪個條件,未傳的不生效;
  • 所有入?yún)⒍甲?#{},安全、可預(yù)編譯。

五、面試回答模板(直接背)

  • 問:MyBatis 動態(tài) SQL 有什么作用?常用在哪些場景?
    • 答:“MyBatis 通過 <if><choose>、<foreach>、<where>、<set> 等標(biāo)簽,在 XML 里按條件動態(tài)拼接 SQL,代替 Java 代碼里手動拼字符串。常用在多條件查詢、批量插入 / 更新、動態(tài)排序、按需更新部分字段、復(fù)雜關(guān)聯(lián)查詢等場景,既提高了可讀性和維護性,又能配合 #{} 和預(yù)編譯保證安全。”

到此這篇關(guān)于MyBatis 中動態(tài) SQL 的作用及執(zhí)行原理解析的文章就介紹到這了,更多相關(guān)mybatis動態(tài)sql使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot項目啟動找不到啟動類的解決

    Springboot項目啟動找不到啟動類的解決

    這篇文章主要介紹了Springboot項目啟動找不到啟動類的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java生成圖片驗證碼功能

    java生成圖片驗證碼功能

    最近在用ssm框架做一個管理系統(tǒng),做到登錄驗證時,需要實現(xiàn)圖片驗證碼功能,今天小編給大家分享基于java制作的圖片驗證碼功能,感興趣的朋友一起看看吧
    2019-12-12
  • SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出)

    SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出)

    這篇文章主要介紹了SpringBoot快速集成jxls-poi(自定義模板,支持本地文件導(dǎo)出,在線文件導(dǎo)出),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java?Selenide?簡介與用法

    Java?Selenide?簡介與用法

    Selenium?是目前用的最廣泛的Web?UI?自動化測試框架,本文給大家介紹下Java?Selenide使用,感興趣的朋友一起看看吧
    2022-01-01
  • Dubbo本地調(diào)試的幾種方式總結(jié)

    Dubbo本地調(diào)試的幾種方式總結(jié)

    dubbo服務(wù)方啟動時需要加載的東西太多,如果跑單元測試把服務(wù)開啟會浪費不少時間,而且單元測試沒法保持服務(wù)一直開啟的狀態(tài),這篇文章主要給大家介紹了關(guān)于Dubbo本地調(diào)試的幾種方式,需要的朋友可以參考下
    2022-11-11
  • Java字符編碼解碼的實現(xiàn)詳解

    Java字符編碼解碼的實現(xiàn)詳解

    本篇文章介紹了,Java字符編碼解碼的實現(xiàn)詳解。需要的朋友參考下
    2013-05-05
  • Java使用OpenCV實現(xiàn)實時對象追蹤的代碼示例

    Java使用OpenCV實現(xiàn)實時對象追蹤的代碼示例

    視覺跟蹤是指通過分析視頻幀來自動追蹤一個或多個移動對象的過程,這項技術(shù)廣泛應(yīng)用于監(jiān)控、人機交互、增強現(xiàn)實和自動駕駛等領(lǐng)域,本文給大家介紹了Java如何使用OpenCV實現(xiàn)實時對象追蹤,需要的朋友可以參考下
    2025-09-09
  • Java實現(xiàn)的雙向匹配分詞算法示例

    Java實現(xiàn)的雙向匹配分詞算法示例

    這篇文章主要介紹了Java實現(xiàn)的雙向匹配分詞算法,結(jié)合完整實例形式詳細分析了雙向匹配分詞算法的原理與java實現(xiàn)技巧,需要的朋友可以參考下
    2017-12-12
  • spring boot實現(xiàn)profiles動態(tài)切換的示例

    spring boot實現(xiàn)profiles動態(tài)切換的示例

    Spring Boot支持在不同的環(huán)境下使用不同的配置文件,該技術(shù)非常有利于持續(xù)集成,在構(gòu)建項目的時候只需要使用不同的構(gòu)建命令就可以生成不同運行環(huán)境下war包,而不需要手動切換配置文件。
    2020-10-10
  • Java設(shè)計模式之觀察者模式_動力節(jié)點Java學(xué)院整理

    Java設(shè)計模式之觀察者模式_動力節(jié)點Java學(xué)院整理

    這篇文章給大家介紹流量java設(shè)計模式之觀察者模式,定義對象間一種一對多的依賴關(guān)系,使得當(dāng)每一個對象改變狀態(tài)。下面通過類圖和實例代碼給大家介紹java設(shè)計模式之觀察者模式,感興趣的朋友一起看看吧
    2017-08-08

最新評論

奉节县| 闽侯县| 邵东县| 清河县| 沂水县| 镶黄旗| 邳州市| 三台县| 长汀县| 宁海县| 裕民县| 启东市| 荔波县| 阿图什市| 米脂县| 福贡县| 桃源县| 安新县| 邻水| 武川县| 高安市| 罗城| 广河县| 温州市| 武宣县| 海门市| 临沭县| 南通市| 容城县| 洪雅县| 饶平县| 福州市| 扎赉特旗| 吉林市| 明星| 屏边| 平顺县| 洛川县| 南召县| 舟曲县| 临海市|