MyBatis动态语句(SQL)

MyBatis动态语句(SQL)

leo 1480 2021-04-10

动态语句

MyBatis动态语句是MyBatis最强大的特性之一,通过动态语句,我们可以更方便地编写SQL语句。

MyBatis中的动态语句主要包括:if、choose(when、otherwise)、trim(where、set)、foreach。

if

含义就像编程语言中的if一样,用于进行条件判断。

例如:

<select id="selectAll" parameterType="User" resultType="User">
	select * from user 
    where gender = #{gender}
    <if test="name != null and name != ''">
    	and name like #{name}
    </if>
</select>

如果没有传入name,那么只会对gender进行匹配,否则对name也进行匹配。

choose、when、otherwise

含义就像编程语言中的switch一样,用于分支选择。

例如:

<select id="selectAll" parameterType="User" resultType="User">
	select * from user 
    where gender = #{gender}
    <choose>
        <when test="name != null and name != ''">
            and name like #{name}
        </when>
    	<when test="address != null and address != ''">
            and address like #{address}
        </when>
        <otherwise>
            and locked = 0
        </otherwise>
    </choose>
</select>

如果没有传入name,就会检查address,如果address也没有传入,那么就会进入otherwise分支。

trim(where、set)

前面的例子中,where后面必然会跟一个条件gender = #{gender},但如果我们将这个条件也放入if中呢。

那么最后的sql就有可能是这样:

//所有参数为空
select * from user where
//第一个参数为空
select * from user wehre and name like 'test'

很显然上述sql语句都包含语法错误。

  1. 通过使用where

    <select id="selectAll" parameterType="User" resultType="User">
    	select * from user 
        <where>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        	<if test="name != null and name != ''">
                and name like #{name}
            </if>
        </where>
    </select>
    

    当where标签有返回值时,会自动在前面插入一个where,返回内容以and或or开头的话会剔除掉。这样就保证了sql语句的正确性。

  2. 通过使用trim

    除了使用where之外,还可以使用trim

    <select id="selectAll" parameterType="User" resultType="User">
    	select * from user 
        <trim prefix="where" prefixOverrides="and |or ">
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        	<if test="name != null and name != ''">
                and name like #{name}
            </if>
        </trim>
    </select>
    

除了在where后的条件之外,还有一种类似的情况,是在update语句中的set后,只有当传入的值非空才更新。

如:

<update id="update" parameterType="User" resultType="Integer">
	update user
    <set>
    	<if test="name != null and name != ''"> name = #{name},</if>
        <if test="gender != null and gender != ''"> gender = #{gender},</if>
        <if test="address != null and address != ''"> address = #{address}</if>
    </set>
    where id = #{id}
</update>

当set标签返回值以,结尾时可以自动剔除。

除了使用set标签外,也可以使用trim

<update id="update" parameterType="User" resultType="Integer">
	update user
    <trim prefix="set" sufixOverrides=",">
    	<if test="name != null and name != ''"> name = #{name},</if>
        <if test="gender != null and gender != ''"> gender = #{gender},</if>
        <if test="address != null and address != ''"> address = #{address}</if>
    </trim>
    where id = #{id}
</update>

foreach

当传入的参数是一个集合时,我们可以通过foreach标签很方便对其进行遍历。

<select id="selectMulti" parameterType="User" resultType="User">
	select * from user 
    where id in
    <foreach item="i" index="index" collection="ids" open="(" separator="," close=")">
    	#{i}
    </foreach>
</select>

注意:当传入参数为List时,collection的值为list,为数组时,collection的值为array,当然也可以通过在参数上加@Param("ids")注解指定名字(上述例子就是)。