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

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

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

在電商平臺的用戶管理模塊中,需要面對多種不同的用戶查詢組合條件。當使用傳統(tǒng)的硬編碼SQL方式時,代碼膨脹到了2000多行,維護成本極高。而引入MyBatis動態(tài)SQL后,同樣的功能僅用300行代碼實現,且可讀性提升了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注入:自動使用預編譯參數
  • 提升可讀性:SQL與Java邏輯解耦
  • 降低出錯率:避免手動拼接錯誤

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

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

業(yè)務場景:根據傳入參數動態(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)建參數對象
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 = ?

參數變化時的SQL差異

傳入參數生成SQL
只設置id=1SELECT * FROM user WHERE id = ?
設置username和passwordSELECT ... WHERE username=? AND password=?
不傳任何參數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):根據前端選擇的50+字段生成查詢
  • 高級搜索功能:支持多條件組合篩選
  • 批量操作:使用foreach處理集合參數
  • 多租戶系統(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的真實數據:運單查詢接口響應時間從120ms降至45ms,代碼維護成本降低70%。但切記:動態(tài)SQL是利器而非銀彈——當邏輯復雜到難以維護時,請考慮改用存儲過程或Elasticsearch等專業(yè)方案!

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

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

相關文章

  • Spring Boot 捕捉全局異常 統(tǒng)一返回值的問題

    Spring Boot 捕捉全局異常 統(tǒng)一返回值的問題

    這篇文章主要介紹了Spring Boot 捕捉全局異常 統(tǒng)一返回值,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • MySQL數據庫之Purge死鎖問題解析

    MySQL數據庫之Purge死鎖問題解析

    這篇文章主要介紹了MySQL數據庫之Purge死鎖問題解析的相關資料,需要的朋友可以參考下
    2017-11-11
  • Java多線程下載網圖的完整案例

    Java多線程下載網圖的完整案例

    這篇文章主要給大家介紹了關于Java多線程下載網圖的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Java中BigDecimal的equals方法和compareTo方法的區(qū)別詳析

    Java中BigDecimal的equals方法和compareTo方法的區(qū)別詳析

    這篇文章主要給大家介紹了關于Java中BigDecimal的equals方法和compareTo方法區(qū)別的相關資料,對于BigDecimal的大小比較,用equals方法的話會不僅會比較值的大小,還會比較兩個對象的精確度,而compareTo方法則不會比較精確度,只比較數值的大小,需要的朋友可以參考下
    2023-11-11
  • SpringBoot如何設置404、500返回統(tǒng)一格式json

    SpringBoot如何設置404、500返回統(tǒng)一格式json

    這篇文章主要介紹了SpringBoot如何設置404、500返回統(tǒng)一格式json問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Mybatis批量插入,返回主鍵ID不成功,巨坑記錄

    Mybatis批量插入,返回主鍵ID不成功,巨坑記錄

    這篇文章主要介紹了Mybatis批量插入,返回主鍵ID不成功,巨坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java JDK17沒有源碼的問題及解決

    Java JDK17沒有源碼的問題及解決

    這篇文章主要介紹了Java JDK17沒有源碼的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • System.getProperty(“l(fā)ine.separator“)含義及意義詳解

    System.getProperty(“l(fā)ine.separator“)含義及意義詳解

    這篇文章主要介紹了System.getProperty(“l(fā)ine.separator“)含義,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • SpringBoot?項目打成?jar后加載外部配置文件的操作方法

    SpringBoot?項目打成?jar后加載外部配置文件的操作方法

    這篇文章主要介紹了SpringBoot?項目打成?jar后加載外部配置文件的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 一篇文章帶你了解JAVA面對對象之繼承與修飾符

    一篇文章帶你了解JAVA面對對象之繼承與修飾符

    這篇文章主要介紹了Java面向對象編程之類的繼承,結合實例形式較為詳細的分析了Java面向對象編程類的概念、功能、使用方法及相關注意事項,需要的朋友可以參考下
    2021-08-08

最新評論

汪清县| 宜昌市| 盘山县| 宁阳县| 额尔古纳市| 且末县| 渝北区| 常德市| 宜黄县| 浑源县| 石阡县| 永康市| 鄯善县| 壤塘县| 舞阳县| 湖口县| 泽州县| 扎鲁特旗| 东乌珠穆沁旗| 南和县| 郯城县| 金昌市| 内乡县| 商水县| 勐海县| 榆林市| 秀山| 宝清县| 津市市| 商丘市| 乐清市| 宁晋县| 泸水县| 鄢陵县| 金沙县| 婺源县| 保德县| 山丹县| 宜丰县| 固安县| 广汉市|