撰寫條件查詢時,最頭痛的是 WHERE 子句的 AND/OR 拼接:第一個條件不需要前綴,後續條件需要,且可能所有條件都不滿足導致 SQL 語法錯誤。
<where> 標籤解決方案<select id="findUsers" resultType="User">
SELECT * FROM users
<where>
<if test="username != null and username != ''">
AND username = #{username}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
</select>
<where> 內容為空 → 不輸出 WHERE 關鍵字AND 或 OR 開頭 → 自動移除首個 AND/ORWHERE + 內容| 條件輸入 | 產生 SQL |
|---|---|
| 所有參數為 null | SELECT * FROM users |
| username="Tom" | SELECT * FROM users WHERE username = ? |
| username="Tom", status=1 | SELECT * FROM users WHERE username = ? AND status = ? |
<trim> 進階替代方案當需要更精細控制時,可使用 <trim> 完全自訂前後綴處理:
<select id="findUsers" resultType="User">
SELECT * FROM users
<trim prefix="WHERE" prefixOverrides="AND |OR">
<if test="username != null"> AND username = #{username} </if>
<if test="email != null"> OR email = #{email} </if>
</trim>
</select>
prefix:前綴關鍵字;prefixOverrides:要移除的開頭字串 (支援多個,用空格分隔)。
<set> 標籤:更新語句的救星同理適用於 UPDATE 的 SET 子句,自動處理尾隨逗號:
<update id="updateUser">
UPDATE users
<set>
<if test="username != null"> username = #{username}, </if>
<if test="email != null"> email = #{email}, </if>
<if test="phone != null"> phone = #{phone} </if>
</set>
WHERE id = #{id}
</update>
<where>/<set>:語意清晰,覆蓋 90% 場景<trim>:需要自訂前後綴、混合 AND/OR 時bind 標籤:複雜條件預先計算,如模糊查詢 <bind name="pattern" value="'%' + keyword + '%'" />MyBatis 動態 SQL 標籤 (where、set、trim) 將條件拼接的煩瑣邏輯內建化,讓開發者專注於業務條件本身,是從寫 SQL 進化到寫「SQL 模板」的關鍵一步。