傳統 JDBC 拼接 SQL 字串痛苦不堪:空格遺漏、逗號殘留、條件組合爆炸。MyBatis 基於 OGNL 表達式 的動態 SQL 標籤,將條件構建邏輯直接寫在映射檔中,徹底解決此痛點。
<select id="dynamicIfTest" resultType="Blog">
SELECT * FROM t_blog WHERE 1=1
<if test="title != null">
AND title = #{title}
</if>
<if test="content != null">
AND content = #{content}
</if>
<if test="owner != null">
AND owner = #{owner}
</if>
</select>
提供參數時自動拼接對應條件,缺省則忽略。
<select id="dynamicChooseTest" resultType="Blog">
SELECT * FROM t_blog WHERE 1=1
<choose>
<when test="title != null"> AND title = #{title} </when>
<when test="content != null"> AND content = #{content} </when>
<otherwise> AND owner = 'owner1' </otherwise>
</choose>
</select>
按順序評估,首個符合的 when 生效,其餘忽略。全不符合時走 otherwise。
<select id="dynamicWhereTest" resultType="Blog">
SELECT * FROM t_blog
<where>
<if test="title != null"> title = #{title} </if>
<if test="content != null"> AND content = #{content} </if>
<if test="owner != null"> AND owner = #{owner} </if>
</where>
</select>
智慧行為:
WHERE 關鍵字AND/OR 開頭,自動移除WHERE(查全表)
<select id="dynamicTrimTest" resultType="Blog">
SELECT * FROM t_blog
<trim prefix="WHERE" prefixOverrides="AND |OR">
<if test="title != null"> title = #{title} </if>
<if test="content != null"> AND content = #{content} </if>
<if test="owner != null"> OR owner = #{owner} </if>
</trim>
</select>
屬性對應:
| 屬性 | 功能 |
|---|---|
| prefix | 內容前加前綴 |
| suffix | 內容後加後綴 |
| prefixOverrides | 移除內容開頭的指定字串 |
| suffixOverrides | 移除內容結尾的指定字串 |
<update id="dynamicSetTest" parameterType="Blog">
UPDATE t_blog
<set>
<if test="title != null"> title = #{title}, </if>
<if test="content != null"> content = #{content}, </if>
<if test="owner != null"> owner = #{owner} </if>
</set>
WHERE id = #{id}
</update>
智慧行為:自動輸出 SET,移除結尾逗號。注意:若所有條件均不滿足(set 內容為空),會拋出異常。
<select id="dynamicForeachTest" resultType="Blog">
SELECT * FROM t_blog WHERE id IN
<foreach collection="list" item="item" index="index"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
屬性詳解:
| 屬性 | 說明 |
|---|---|
| collection | 關鍵,三種情況值不同(見下表) |
| item | 迭代元素別名 |
| index | 索引別名(List 為索引,Map 為鍵) |
| open/separator/close | 包圍字串、分隔符、結尾字串 |
| 傳參類型 | Java 介面 | collection 值 |
|---|---|---|
| 單參數 List | List<Blog> dynamicForeachTest(List<Integer> ids) | list |
| 單參數 Array | List<Blog> dynamicForeach2Test(int[] ids) | array |
| 多參數/Map | List<Blog> dynamicForeach3Test(Map<String,Object> params) | Map 中的 Key(如 ids) |
<select id="dynamicForeach3Test" resultType="Blog">
SELECT * FROM t_blog
WHERE title LIKE "%"#{title}"%"
AND id IN
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
-- Java 調用
Map<String, Object> params = new HashMap<>();
params.put("ids", Arrays.asList(1,2,3,6,7,9));
params.put("title", "中國");
blogMapper.dynamicForeach3Test(params);
test="@util@isNotEmpty(title)"#{param} 使用預編譯,${param} 直接拼接(僅用於表名/欄位名等不可參數化場景)