[学习笔记] MyBatis之动态SQL

# 学习 # · 2020-11-24

使用动态SQL完成多条件查询

1、动态SQL基于OGNL的表达式,用于实现动态SQL的元素如下:

(1)if:利用if实现简单的条件选择。

(2)choose(when、otherwise):相当于switch语句。

(3)where:简化SQL语句中where的条件判断,智能处理and和or

(4)set:解决动态更新语句。

(5)trim:可以灵活地去除多余的关键字。

(6)foreach:迭代一个集合,通常用于in条件。

2、使用if+where实现多条件查询:

<select id="getStudent" resultType="com.mybatis.pojo.Student">
    select * from student
    <!--
    where元素标签会自动识别其标签内是否有返回值
    若有,就插入一个where
    若该标签返回的内容是以and和or开头,会自动剔除and和or
    -->
    <where>
        <if test="name != null and name != ''">
            and name like CONCAT ('%',#{name},'%') 
        </if>
        <if test="tid != null">
            and tid = #{tid}
        </if>
    </where>
</select>

3、使用if+trim实现多条件查询:

<select id="getStudent" resultType="com.mybatis.pojo.Student">
    select * from student
    <!--
    trim元素标签会自动识别其标签内是否有返回值
    若有,会在自己包含的内容前后进行相应处理(加前后缀、覆盖前后内容)
    prefix:前缀
    suffix:后缀
    prefixOverrides:对于trim包含内容的首部进行指定内容的忽略
    suffixOverrides:对于trim包含内容的首尾部进行指定内容的忽略
    -->
    <!--如果trim标签内有返回值,则在返回的语句前面加上where,并忽略首部的and或者or-->
    <trim prefix="where" prefixOverrides="and | or">
        <if test="name != null and name != ''">
            and name like CONCAT ('%',#{name},'%') 
        </if>
        <if test="tid != null">
            and tid = #{tid}
        </if>
    </trim>
</select>

使用动态SQL实现更新操作

1、使用if+set改造更新操作:

<update id="editStudent" parameterType="Student">
    update student
    <!--
    set元素标签会在包含的语句前输出一个set
    若包含的语句以逗号结束,会自动把逗号忽略掉
    配合if元素标签动态更新需要修改的字段
    -->
    <set>
        <if test="name != null">name=#{name},</if>
        <if test="tid != null">tid=#{tid},</if>
    </set>
    where id = #{id}
</update>

2、使用if-trim改造修改操作:

<update id="editStudent" parameterType="Student">
    update student
    <!--如果trim内有返回值,则在语句前面加上set,并省略最后面的逗号,并在后面加上where id=#{id}-->
    <trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
        <if test="name != null">name=#{name},</if>
        <if test="tid != null">tid=#{tid},</if>
    </trim>
</update>

使用foreach完成复杂查询

1、MyBatis入参为Array数组类型的foreach迭代:

<!-- foreach_array -->
<select id="getStudent" resultMap="studentInfo">
    select * from student where tid in 
    <!--
    item:表示集合中每一个元素进行迭代时的别名
    index:指定一个名称,用于表示在迭代过程中每次迭代到的位置
    open:表示该语句以什么开始
    separator:表示在每次进行迭代之间以什么符号作为分隔符
    close:表示该语句以什么结束
    collection:传入的属性,参数类型为list/array
    -->
    <foreach collection="array" item="Tids" open="(" separator="," close=")">
        #{Tids}
    </foreach>
    <!--SQL语句相当于select * from student where tid in (1 or 2)-->
</select>

2、MyBatis入参为List类型的foreach迭代:

<!-- foreach_list -->
<select id="getStudent" resultMap="studentInfo">
    select * from student where tid in
    <foreach collection="list" item="Tids" open="(" separator="," close=")">
        #{Tids}
    </foreach>
</select>

3、MyBatis入参为Map类型的foreach迭代:

<!-- foreach_map -->
<select id="getStudent" resultMap="studentInfo">
    select * from student where tid in
    <!--
    collection="Tids"获取Map中key为id的值
    -->
    <foreach collection="Tids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

4、小结:

(1)MyBatis接收的参数类型:基本类型、对象、List、数组、Map。

(2)无论MyBatis的入参是哪种参数类型,MyBatis都会将参数放在一个Map中,对于单参入参的情况:

①若入参为基本类型:变量名作为key,变量值为value,此时生成的Map只有一个元素。

②若入参为对象:对象的属性名为key,属性值为value。

③若入参为List:默认“list”为key,该List为value。

④若参数为数组:默认“array”为key,该数组即为value。

⑤若参数为Map:键值不变。

5、choose、when、otherwise:

<!-- 查询用户列表(choose) -->
<select id="getUserList_choose" resultType="User">
    select * from smbms_user where 1=1
    <choose>
        <when test="userName != null and userName != ''">
            and userName like CONCAT ('%',#{userName},'%')
        </when>
        <when test="userCode != null and userCode != ''">
            and userCode like CONCAT ('%',#{userCode},'%')
        </when>
        <when test="userRole != null">
            and userRole=#{userRole}
        </when>
        <otherwise>
            <!-- and YEAR(creationDate) = YEAR(NOW()) -->
            and YEAR(creationDate) = YEAR(#{creationDate})
        </otherwise>
    </choose>
</select>
如无特殊说明,本博所有文章均为博主原创。

如若转载,请注明出处:一木林多 - https://www.l5v.cn/archives/189/

评论