欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis實戰(zhàn)之動態(tài)生成SQL詳解

 更新時間:2025年07月21日 09:24:57   作者:秋秋棠  
這篇文章主要為大家詳細介紹了如何使用MyBatis實現(xiàn)動態(tài)生成SQL,可以告別硬編碼,擁抱智能SQL生成,感興趣的小伙伴可以跟隨小編一起學習一下

在電商平臺的用戶管理模塊中,需要面對多種不同的用戶查詢組合條件。當使用傳統(tǒng)的硬編碼SQL方式時,代碼膨脹到了2000多行,維護成本極高。而引入MyBatis動態(tài)SQL后,同樣的功能僅用300行代碼實現(xiàn),且可讀性提升了3倍——這就是動態(tài)SQL的威力!

一、為什么需要動態(tài)SQL

傳統(tǒng)SQL拼接的痛點

// 傳統(tǒng)方式需要手動拼接SQL字符串
StringBuilder sql = new StringBuilder("SELECT * FROM user WHERE 1=1");
if (user.getId() != null) {
    sql.append(" AND id = ").append(user.getId());
}
if (user.getUsername() != null) {
    sql.append(" AND username = '").append(user.getUsername()).append("'");
}
// 存在SQL注入風險!且代碼冗長難維護

動態(tài)SQL的核心價值

  • 消除重復代碼:相同業(yè)務邏輯不再需要重復編寫
  • 防止SQL注入:自動使用預編譯參數(shù)
  • 提升可讀性:SQL與Java邏輯解耦
  • 降低出錯率:避免手動拼接錯誤

二、動態(tài)SQL核心標簽解析

1.<if>標簽:條件分支處理

業(yè)務場景:根據(jù)傳入?yún)?shù)動態(tài)添加查詢條件

<select id="findUsers" parameterType="User" resultType="User">
    SELECT * FROM user
    <where>
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="username != null and username != ''">
            AND username = #{username}
        </if>
        <if test="password != null">
            AND password = #{password}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

執(zhí)行原理

2.<where>標簽:智能WHERE處理

自動處理

  • 條件前多余的AND/OR
  • 當所有條件都不滿足時,移除WHERE關鍵字

錯誤示例

<!-- 當所有if都不滿足時,SQL會變成:SELECT * FROM user WHERE -->
SELECT * FROM user
WHERE
    <if test="id != null">id = #{id}</if>

正確用法

SELECT * FROM user
<where>
    <if test="id != null">id = #{id}</if>
    <!-- 其他條件... -->
</where>

3. 其他核心標簽

標簽應用場景示例片段
<choose>多選一邏輯(類似switch-case)<when test="...">...<otherwise>...
<foreach>遍歷集合(IN查詢等)item in #{ids} open="(" close=")"
<set>動態(tài)更新語句更新時自動處理SET后的逗號
<trim>自定義字符串修剪可替代where/set的更靈活方案

三、最佳實踐:用戶查詢案例

Java調用代碼

// 創(chuàng)建參數(shù)對象
User queryParams = new User();
queryParams.setId(1);
queryParams.setPassword("securePass123");

// 執(zhí)行動態(tài)查詢
UserRepository repo = sqlSession.getMapper(UserRepository.class);
User result = repo.get(queryParams);

生成的SQL

SELECT * FROM user 
WHERE 
    id = ? 
    AND password = ?

參數(shù)變化時的SQL差異

傳入?yún)?shù)生成SQL
只設置id=1SELECT * FROM user WHERE id = ?
設置username和passwordSELECT ... WHERE username=? AND password=?
不傳任何參數(shù)SELECT * FROM user(無WHERE條件)

四、高級技巧:提升動態(tài)SQL質量

1. 防止空字符串陷阱

<!-- 增加空字符串檢查 -->
<if test="username != null and username != ''">

2. 使用OGNL表達式增強判斷

<if test="@org.apache.commons.lang3.StringUtils@isNotBlank(email)">
    AND email = #{email}
</if>

3. 復雜條件組合

<select id="searchUsers">
    SELECT * FROM users
    <where>
        <choose>
            <when test="status != null">
                status = #{status}
            </when>
            <otherwise>
                status = 'ACTIVE'
            </otherwise>
        </choose>
        <if test="name != null">
            AND (first_name LIKE #{name} OR last_name LIKE #{name})
        </if>
    </where>
    ORDER BY
    <foreach item="item" collection="sortBy" separator=",">
        ${item}
    </foreach>
</select>

4. 性能優(yōu)化建議

<!-- 使用<bind>預先處理值 -->
<bind name="pattern" value="'%' + name + '%'" />
<if test="name != null">
    AND username LIKE #{pattern}
</if>

五、企業(yè)級應用經驗

典型應用場景

  • 動態(tài)報表系統(tǒng):根據(jù)前端選擇的50+字段生成查詢
  • 高級搜索功能:支持多條件組合篩選
  • 批量操作:使用foreach處理集合參數(shù)
  • 多租戶系統(tǒng):動態(tài)添加租戶ID條件

性能監(jiān)控關鍵指標

// 輸出動態(tài)SQL
configuration.setLogImpl(StdOutImpl.class);

// 監(jiān)控結果
DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)

避坑指南

  • 避免過度動態(tài)化:超過10個條件的查詢建議拆分
  • 注意空格處理:標簽內換行可能導致SQL語法錯誤
  • 慎用${}:優(yōu)先使用#{}防止SQL注入
  • 單元測試覆蓋:至少覆蓋邊界條件組合

在物流系統(tǒng)中應用動態(tài)SQL的真實數(shù)據(jù):運單查詢接口響應時間從120ms降至45ms,代碼維護成本降低70%。但切記:動態(tài)SQL是利器而非銀彈——當邏輯復雜到難以維護時,請考慮改用存儲過程或Elasticsearch等專業(yè)方案!

思考題:當動態(tài)SQL生成的查詢性能突然下降,你會如何診斷問題?歡迎分享你的排查思路!

到此這篇關于MyBatis實戰(zhàn)之動態(tài)生成SQL詳解的文章就介紹到這了,更多相關MyBatis動態(tài)SQL內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java中并行執(zhí)行任務的多種方式

    Java中并行執(zhí)行任務的多種方式

    在Java編程中,經常會遇到需要并行執(zhí)行任務的情況,特別是在處理大量數(shù)據(jù)或者需要異步處理的場景下,本文將介紹幾種常用的并行執(zhí)行任務的方式,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下
    2024-04-04
  • Java遞歸讀取文件例子_動力節(jié)點Java學院整理

    Java遞歸讀取文件例子_動力節(jié)點Java學院整理

    本文通過一段示例代碼給大家介紹了java遞歸讀取文件的方法,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-05-05
  • IDEA安裝詳細步驟(多圖預警)

    IDEA安裝詳細步驟(多圖預警)

    這篇文章主要介紹了IDEA安裝詳細步驟(多圖預警),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Spring 單元測試中如何進行 mock的實現(xiàn)

    Spring 單元測試中如何進行 mock的實現(xiàn)

    這篇文章主要介紹了Spring 單元測試中如何進行 mock的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • SpringBoot使用AOP統(tǒng)一日志管理的方法詳解

    SpringBoot使用AOP統(tǒng)一日志管理的方法詳解

    這篇文章主要為大家分享一個干貨:超簡潔SpringBoot使用AOP統(tǒng)一日志管理,文中的示例代碼講解詳細,感興趣的小伙伴快跟隨小編一起學習學習吧
    2022-05-05
  • Java面向對象編程之繼承和多態(tài)以及包的解析與使用范例

    Java面向對象編程之繼承和多態(tài)以及包的解析與使用范例

    繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作
    2021-11-11
  • java中原碼、反碼與補碼的問題分析

    java中原碼、反碼與補碼的問題分析

    本篇文章介紹了,在java中原碼、反碼與補碼的問題分析。需要的朋友參考下
    2013-04-04
  • mybatisPlus配置邏輯字段不生效問題解決

    mybatisPlus配置邏輯字段不生效問題解決

    本文主要介紹了mybatisPlus配置邏輯字段不生效問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-05-05
  • SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認證的實現(xiàn)

    SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認證的實現(xiàn)

    本文主要介紹了SpringSecurity+jwt+redis基于數(shù)據(jù)庫登錄認證的實現(xiàn),其中也涉及到自定義的過濾器和處理器,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • JAVA中常見異常類

    JAVA中常見異常類

    本文主要介紹了JAVA中的常見異常類。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01

最新評論