Mybatis(六):動態 SQL

官方介紹:

MyBatis 的強大特性之一便是它的動態 SQL。如果你有使用 JDBC 或其他類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句有多麼痛苦。拼接的時候要確保不能忘了必要的空格,還要注意省掉列名列表最後的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。  

通常使用動態 SQL 不可能是獨立的一部分,MyBatis 當然使用一種強大的動態 SQL 語言來改進這種情形,這種語言可以被用在任意的 SQL 映射語句中。  

動態 SQL 元素和使用 JSTL 或其他類似基於XML的文本處理器相似。在 MyBatis 之前的版本中,有很多的元素需要來了解。MyBatis 3 大大提升了它們,現在用不到原先一半的元素就可以了。MyBatis 採用功能強大的基於 OGNL 的表達式來消除其他元素。

簡單來講,就是掌握四個標記

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach (之前講過了)

一、<if>

選擇性條件查找

    <!-- 選擇性查找 -->
    <select id="selectSelective" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        WHERE 1 = 1
        <if test="username != null and username != '' ">
            and username LIKE CONCAT('%',#{username},'%')
        </if>
        <if test="age != null and age != '' ">
            and age = #{age}
        </if>
    </select>

二、<where>, <set>, <trim>

注意上面的 1=1,爲了防止兩個條件都不存在時,SQL執行報錯,更好的解決方式是使用<where>

表示<where> 元素知道只有在一個以上的if條件有值的情況下才去插入“WHERE”子句。而且,若最後的內容是“AND”或“OR”開頭的,where 元素也知道如何將他們去除。

    <select id="selectSelective" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        <where>
            <if test="username != null and username != '' ">
                username LIKE CONCAT('%',#{username},'%')
            </if>
            <if test="age != null and age != '' ">
                and age = #{age}
            </if>
        </where>
    </select>

選擇性更新

注意<set>,能夠過濾後面的逗號

    <!-- 選擇性更新 -->
    <update id="updateSelective" parameterType="cn.saytime.domain.User">
        UPDATE tb_user
        <set>
            <if test="username != null and username != '' ">
                username = #{username},
            </if>
            <if test="age != null and age != '' ">
                age = #{age}
            </if>
        </set>
        WHERE id = #{id}
    </update>

如果上面兩種都不滿足要求的情況下,可以自定義<trim>

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  username = #{username}
  ...
</trim>


<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

三、<choose>, <when>, <otherwise>

    <!-- 選擇性查找2:有姓名則查找姓名,沒有姓名看是否有年齡,有年齡查年齡,都沒有默認查18歲以上的 -->
    <select id="selectSelective2" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        <where>
            <choose>
                <when test="username != null and username != '' ">
                    username LIKE CONCAT('%',#{username},'%')
                </when>
                <when test="age != null and age != '' ">
                    and age = #{age}
                </when>
                <otherwise>
                    and age > 18
                </otherwise>
            </choose>
        </where>
    </select>

四、<foreach>

<!-- 批量保存用戶,並返回每個用戶插入的ID -->
<insert id="batchSave" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO `test`.`tb_user`(`username`, age)
    VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.username}, #{item.age})
    </foreach>
</insert>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章