MyBatis 的動態 SQL 功能極大簡化了條件查詢的編寫,但 <if> 標籤若使用不當,極易產生語法錯誤的 SQL。最經典的坑就是:當所有條件都不滿足時,SQL 殘留孤立的 WHERE 關鍵字;或首個條件失效導致殘留 AND/OR。本文深度解析 <where>、<trim>、<set> 標籤的智能修剪機制,助你寫出健壯的動態 SQL。
假設我們要實現一個部落格多條件查詢,初學者常這樣寫:
<select id="findBlogs" resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="userId != null"> state = 'ACTIVE' </if>
<if test="title != null"> AND title LIKE #{title} </if>
<if test="author != null"> AND author = #{author} </if>
</select>
| 參數情況 | 生成 SQL | 結果 |
|---|---|---|
| 所有參數為 null | SELECT * FROM BLOG WHERE | 語法錯誤 |
| userId=null, title=xxx | SELECT * FROM BLOG WHERE AND title LIKE 'xxx' | 語法錯誤 |
<where> 是 MyBatis 提供的智能標籤,具備兩大核心功能:
WHERE 關鍵字。AND 或 OR,會自動移除。<select id="findBlogs" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="userId != null"> state = 'ACTIVE' </if>
<if test="title != null"> AND title LIKE #{title} </if>
<if test="author != null"> AND author = #{author} </if>
</where>
</select>
| 參數情況 | 生成 SQL | 說明 |
|---|---|---|
| 所有參數為 null | SELECT * FROM BLOG | 自動移除 WHERE |
| userId=null, title=xxx | SELECT * FROM BLOG WHERE title LIKE 'xxx' | 自動修剪首個 AND |
| userId=1, title=xxx | SELECT * FROM BLOG WHERE state='ACTIVE' AND title LIKE 'xxx' | 正常拼接 |
動態更新同樣面臨逗號殘留問題,MyBatis 提供 <set> 標籤專門解決:
<update id="updateBlog">
UPDATE BLOG
<set>
<if test="title != null"> title = #{title}, </if>
<if test="content != null"> content = #{content}, </if>
<if test="author != null"> author = #{author}, </if>
</set>
WHERE id = #{id}
</update>
<set> 會自動移除最後一個生效條件尾部的逗號,若所有條件皆無效則不生成 SET 子句(需注意業務邏輯是否允許無字段更新)。
當 <trim> 提供完全可控的前後綴處理:
<!-- 等價於 -->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="state != null"> AND state = #{state} </if>
<if test="title != null"> AND title LIKE #{title} </if>
</trim>
<!-- 等價於 -->
<trim prefix="SET" suffixOverrides=",">
<if test="name != null"> name = #{name}, </if>
<if test="age != null"> age = #{age}, </if>
</trim>
prefix:內容非空時前置的字串prefixOverrides:移除內容開頭匹配的字串(支援多值用空格分隔)suffix:內容非空時後綴的字串suffixOverrides:移除內容結尾匹配的字串<where>,簡潔且語義清晰。<set>,自動處理逗號問題。<trim> 實現自定義前後綴修剪。<if> 內部 SQL 片段前統一加空格(如 AND ...),確保拼接後可讀性。避坑口訣:動態 SQL 寫條件,
where標籤最貼心;首個AND別擔心,自動修剪零負擔。更新用set別犯愁,尾部逗號自消除。複雜場景trim來湊,前後綴隨心控制。
掌握 MyBatis 動態 SQL 的智能標籤,能讓你從繁瑣的字串拼接邏輯中解脫,專注於業務邏輯本身,編寫出既優雅又健壯的持久層代碼。