在Mapper.xml中写复杂的动态SQL语句

发布时间 2023-07-31 10:33:25作者: sunny123456

在Mapper.xml中写复杂的动态SQL语句
原文链接:https://blog.csdn.net/qq_42108331/article/details/131398433

说明:在三层架构开发中,使用Mybatis框架操作数据库有两种方式,一种是在Mapper类里的方法上加注解(@Select、@Insert等),另一种是在Mapper.xml文件的标签内写SQL语句。第二种方式相比第一种,具有更强的延展性,可以使用一些标签,书写一些复杂的SQL语句。以下是五种比较常见的使用场景。

条件查询

场景:前端会传一些条件,需要我们根据这些条件来查询数据,另外这些条件不一定全都会有,可能为null。例如下面CSDN的内容管理,文章有状态、日期、分类、关键字等,这些条件都会传到后端,没有的值为null,需要后端根据这一组条件中有内容的条件来查询数据。

在这里插入图片描述

此时,就可以使用xml中的where和if标签,判断传入的条件值是否为null,以此来拼接SQL,达到目的

    <!--表的全字段名-->
    <sql id="fullField">id, name, status, type, date....</sql>
    <!--条件查询-->
    <select id="selectEssay" resultType="结果需要封装的javaBean对象的全类名,如文章对象">
        select 
            <include refid="fullField"/>
        from 表名
        <where>
            <if test="status != null">
                and status=1
            </if>
            <if test="type != null">
                and type=#{type}
            </if>
            <if test="dateStart != null and dateEnd != null">
                and date bewteen #{dateStart}, #{dateEnd}
            </if>
        </where>
    </select>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

更新数据

场景:更新对象数据,通常也是前端传过来一个对象ID+需要修改的字段和值,需要我们封装成一个新对象,然后根据对象中的内容,去更新数据库中的对应表、对应ID记录的数据。此时,就需要使用SQL语句来判断,对象中有值的字段才修改,没有值的字段不修改。

在xml中,可以这样写:

    <!--更新文章-->
    <update id="updateEssay">
        update 表名
        <set>
            <if test="name != null">name = #{name},</if>
            <if test="type != null">type = #{type},</if>
            <if test="status != null">status = #{status},</if>
            ....
        </set>
        where id = #{id}
    </update>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

需要注意,每个字段末尾要加逗号(,)

批量删除

场景:批量删除操作,通常前端会传过来一组ID集合/数组,需要我们根据这一组ID批量删除数据库中对应的记录。

在xml中,可以这样写:

    <!--根据ID批量删除文章-->
    <delete id="deleteEssaysById">
        delete from 表名 where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

collection:集合/数组名,名称要与Mapper类中对应方法的形参名一致;

item:表示集合/数组中的每一位元素的名称,即下面语句中#{}内表示的内容;

separator:表示元素之间的间隔符;

open:表示以下语句以什么开头;

close:表示以下语句以什么结尾;

通过这种方式,拼接出来的内容,实际上就是语句 “delete from 表名 where id in” 后面的内容

批量添加

场景:因为业务中一对多的关系非常普遍,在添加一条记录(一的一方)时,同时需要将该对象中的对象集合(多的一方)批量添加到对应的数据库表中。比如添加一条教师记录,需要同时添加多条学生记录,表示该教师管理下的多名学生。

在xml文件中,可以这样写:

    <!--批量添加学生-->
    <insert id="insertStudents">
        insert into 学生表名(teacher_id,name,age...) values
        <foreach collection="students" separator="," item="s">
            (#{s.teacher_id},#{s.name},#{s.age}...)
        </foreach>
    </insert>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

总结

除了以上四种场景外,可以使用resultMap标签,设置多表查询后的字段名,设置完之后SQL语句查询的结果就可以直接返回封装成一个对象,返回给前端,非常方便(参考:http://t.csdn.cn/FAv3n)。

注:本文章中的xml代码为非正式代码,不可直接复制使用