1. 程式人生 > 實用技巧 >Mybaties——動態sql

Mybaties——動態sql

動態 SQL 是 MyBatis 的強大特性之一。如果你使用過 JDBC 或其它類似的框架,你應該能理解根據不同條件拼接 SQL 語句有多痛苦,例如拼接時要確保不能忘記新增必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL,可以徹底擺脫這種痛苦。

如果你之前用過 JSTL 或任何基於類 XML 語言的文字處理器,你對動態 SQL 元素可能會感覺似曾相識。在 MyBatis 之前的版本中,需要花時間瞭解大量的元素。藉助功能強大的基於 OGNL 的表示式,MyBatis 3 替換了之前的大部分元素,大大精簡了元素種類,現在要學習的元素種類比原來的一半還要少。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

理解:在sql層面執行邏輯程式碼

  1. 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寫的是集合中的元素型別,並不是集合本身

  2. 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

  3. 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>
    
  4. 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定義了迭代結束放置的字串

  5. 補充:sql片段
    類似於前端元件的概念
    通過<sql id="">定義元件,通過<include refid="">引用元件
    注意:
    (1). 最好基於單表來定義SQL片段
    (2). 不要存在where標籤