MyBatis基礎:MyBatis動態SQL(3)

libingql發表於2017-09-05

1. 概述

  MyBatis中動態SQL包括元素:

元素作用備註
if 判斷語句 單條件分支判斷
choose(when、otherwise) 相當於Java中的case when語句 多條件分支判斷
trim(where、set) 輔助元素 用於處理SQL拼接問題
foreach 迴圈語句 用於in語句等列舉條件

2. if元素

  if元素是最常用的判斷語句,常與test屬性聯合使用。

2.1 if

<resultMap id="baseResultMap" type="com.libing.helloworld.model.Role">
    <id property="id" column="id" />
    <result property="roleName" column="role_name" />
</resultMap>
<select id="findBySearchText" resultMap="baseResultMap">
    SELECT
        id,
        role_name
    FROM
        role
    WHERE 1 = 1
    <if test="searchText != null and searchText != ''">
        AND role_name LIKE CONCAT('%', #{searchText,jdbcType=VARCHAR}, '%')
    </if>
    ORDER BY id ASC
</select>

2.2 if + where

<select id="findBySearchText" resultMap="baseResultMap">
    SELECT
        id,
        role_name
    FROM
        role
    <where>
        <if test="id > 0">
            id >= #{id}
        </if>
        <if test="searchText != null and searchText != ''">
            AND role_name LIKE CONCAT(CONCAT('%',#{searchText,jdbcType=VARCHAR}),'%')
        </if>
    </where>        
    ORDER BY id ASC
</select>

  MyBatis中where標籤會判斷如果所包含的標籤中有返回值,則插入一個‘where’。此外,如果標籤返回的內容是以AND或OR開頭,則自動刪除開頭的AND或OR。

2.3 if + set

<update id="update" parameterType="com.libing.helloworld.model.Role">
    UPDATE role
    <set>
        <if test="roleName != null and roleName != ''">
            role_name = #{roleName},
        </if>
        <if test="remark != null and remark != ''">
            remark LIKE CONCAT('%', #{remark, jdbcType=VARCHAR}, '%')
        </if>
    </set>
    WHERE id = #{id}
</update>

  上面形式,當ramark=null時,動態SQL語句會由於多出一個“,”而錯誤。

3. choose(when,otherwise)元素

<select id="findByCondition" resultMap="baseResultMap">
    SELECT
        id,
        role_name
    FROM
        role
    <where>
        <choose>
            <when test="id > 0">
                id >= #{id}
            </when>
            <otherwise>
                AND role_name LIKE CONCAT('%', #{roleName, jdbcType=VARCHAR}, '%')
            </otherwise>
        </choose>
    </where>
    ORDER BY id ASC
</select>

4.trim元素

4.1 trim:if + where

<select id="findByCondition" resultMap="baseResultMap">
    SELECT
        id,
        role_name
    FROM
        role
    <trim prefix="where" prefixOverrides="AND | OR">
        <if test="id > 0">
            id >= #{id}
        </if>
        <if test="roleName != null and roleName != ''">
            AND role_name = LIKE CONCAT('%', #{roleName, jdbcType=VARCHAR}, '%')
        </if>
    </trim>
    ORDER BY id ASC
</select>

4.2 trim:if + set

<update id="update" parameterType="com.libing.helloworld.model.Role">
    UPDATE role
    <trim prefix="set" suffixOverrides=",">
        <if test="roleName != null and roleName != ''">
            role_name = #{roleName},
        </if>
        <if test="remark != null and remark != ''">
            remark LIKE CONCAT('%', #{remark, jdbcType=VARCHAR}, '%')
        </if>
    </trim>
    WHERE id = #{id}
</update>

5. foreach元素

  foreach元素是一個迴圈語句,作用是遍歷集合,支援遍歷陣列、List、Set介面的集合。

import org.apache.ibatis.annotations.Param;
List<Role> findByIds(@Param("ids") List<Integer> ids);
<select id="findByIds" resultMap="baseResultMap">
    SELECT
        id,
        role_name
    FROM
        role
    WHERE id IN
    <foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
    ORDER BY id ASC
</select>

  其中,

    collection:傳入的引數名稱,可以是一個陣列、List、Set等集合

    item:迴圈中當前的元素

    index:當前元素在集合的位置下標

    open和close:包裹集合元素的符號

    separator:各個元素的間隔符

int insertBatch(List<Role> list);
<insert id="insertBatch" parameterType="java.util.List">
    INSERT role
    (
        role_name
    )
    VALUES
    <foreach collection="list" item="item" index="index" separator=",">
    (
        #{item.roleName}
    )
    </foreach>
</insert>

6. bind元素

  bind元素的作用是通過OGNL表示式去自定義一個上下文變數。

List<Role> findBySearchText(@Param("searchText") String searchText);
<select id="findBySearchText" resultMap="baseResultMap">
    <bind name="pattern_searchText" value="'%' + searchText + '%'"/>
    SELECT
        id,
        role_name
    FROM
        role
    WHERE
        role_name LIKE #{pattern_searchText}
</select>

  其中,

    searchText:傳入的引數名稱

相關文章