Mybaties——動態sql
動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。
如果你之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表示式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
理解:在sql層面執行邏輯程式碼
-
if
根據不同的條件(包括無條件)進行查詢,大大降低了程式碼的冗餘
<select id="queryByIf" parameterType="map" resultType="userBean"> SELECT * FROM user WHERE 1=1 <if test="UId != null"> AND UId = #{UId} </if> <if test="UName != null"> AND UName = #{UName} </if> </select>
注:這裡resultType寫的是集合中的元素型別,並不是集合本身
-
chose,when,otherwise
我們不想使用所有的條件,而只是想從多個條件中選擇一個使用。
<select id="queryByIf" parameterType="map" resultType="userBean"> SELECT * FROM user WHERE <choose> <when test="UId != null"> UId = #{UId} </when> <when test="UName != null"> UName = #{UName} </when> <otherwise> 1=1 </otherwise> </choose> </select>
注:這個語句類似swith,choose->switch,when->case,otherwise->default
-
trim、where、set
where 元素只會在子元素返回任何內容的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除。
set 元素會動態地在行首插入 SET 關鍵字,並會刪掉額外的逗號(這些逗號是在使用條件語句給列賦值時引入的)。
trim可以完成對兩者的實現與優化
where使用:
<select id="queryByIf" parameterType="map" resultType="userBean"> SELECT * FROM user <where> <if test="UName != null"> AND UState = #{UState} </if> <choose> <when test="UId != null"> AND UId = #{UId} </when> <otherwise> AND 1=1 </otherwise> </choose> </where> </select>
注:這裡的where寫了之後,原句中的where就不用寫了,在程式碼執行過程,where標籤能夠自動補上where,並且去除不需要的AND(不會補上)
set使用:
<update id="updateById" parameterType="map"> UPDATE user <set> <if test="UState != null">UState = #{UState},</if> <choose> <when test="UName != null"> UName = #{UName}, </when> <when test="USet != null"> USet = #{USet}, </when> </choose> </set> WHERE UId = #{UId} </update>
注:這裡的set寫了之後,原句中的set也會自動補全,並且去除不需要的','(不會補上)
trim的定義格式:
實現where
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
實現set
<trim prefix="SET" suffixOverrides=","> ... </trim>
-
foreach使用
動態 SQL 的另一個常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件語句的時候)
<select id="queryListByForeach" parameterType="map" resultType="userBean"> SELECT * FROM user <where> <foreach collection="USets" item="item" open="(" separator="OR" close=")"> USet = #{item} </foreach> </where> </select>
說明:主要解釋一下foreach中的幾個引數,這裡collection是map中的一個集合,Uset為集合中的一個引數(名字隨意),open定義了迭代開始所放置的字串,separator定義的是迭代時的分隔符,close定義了迭代結束放置的字串
-
補充:sql片段
類似於前端元件的概念
通過<sql id="">定義元件,通過<include refid="">引用元件
注意:
(1). 最好基於單表來定義SQL片段
(2). 不要存在where標籤