MyBatis基础:MyBatis动态SQL(3)

时间:2021-10-21 05:08:00

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:传入的参数名称