• Mybatis 动态Sql标签使用总结


    一、前言

    常用的动态sql标签包括 if、choose(when、otherwise)、trim(where、set)、foreach。

    二、标签介绍

    2.1、if 标签

    1、动态拼接查询条件

    select DISTINCT ksid as id,ksdm as cd , ksmc as na ,id_org ,1 as fg_active,kspydm as py FROM
            V_CIS_RO_USER
            WHERE 1=1
            <if test="orgId != null">
                AND id_org = #{orgId}
            </if>
            <if test="userId != null">
                AND YHID = #{userId}
            </if>
            <if test="id != null">
                AND ksid = #{id}
            </if>
            <if test="search != null and  search != '' ">
                and  kspydm LIKE concat('%', concat(#{search}, '%'))
            </if>
            ORDER BY kspydm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2、动态选择不同的执行sql

    根据输入参数unitType的不同情况来join不同的表查询结果集。

    <select id="getAdjRatios" resultType="com.fp.epower.model.dto.PowerPredictAdjDto">
            <if test="unitType == null">
                SELECT a.*,b.date,b.status FROM power_forecast_adjust_data a
                LEFT JOIN power_forecast_adjust_info b
                ON a.info_id = b.id
            </if>
            <if test="unitType != null and unitType == 1">
                SELECT a.*,b.date,b.status,c.dispatch_name unitName FROM power_forecast_adjust_data a
                LEFT JOIN power_forecast_adjust_info b
                ON a.info_id = b.id
                LEFT JOIN gen_set c
                ON a.unit_id = c.id
            </if>
            <if test="unitType != null and unitType == 2">
                SELECT a.*,b.date,b.status,c.abbreviation unitName FROM power_forecast_adjust_data a
                LEFT JOIN power_forecast_adjust_info b
                ON a.info_id = b.id
                LEFT JOIN dic_power_plant_info c
                ON a.unit_id = c.id
            </if>
            <where>
                <if test="status != null">
                    b.status = #{status}
                </if>
                <if test="unitType != null and unitType != 0">
                    AND a.unit_type = #{unitType}
                </if>
                <if test="date != null">
                    AND b.date = #{date}
                </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
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    2.2、choose(when、otherwise) 标签

    如果拼接的查询条件存在多个分支,可以使用 choose(类似于switch关键字)

    <select id="getAdjRatio" resultType="java.lang.String">
            SELECT ratio FROM power_forecast_adjust_data a
            LEFT JOIN power_forecast_adjust_info b
            ON a.info_id = b.id
            <choose>
                <when test="status != null and status != 0">
                    b.`status` = #{status}
                </when>
                <when test="unitType != null and unitType != 0">
                    AND a.unit_type = #{unitType}
                </when>
                <when test="unitId != null and unitId != ''">
                    AND a.unit_id = #{unitId}
                </when>
                <when test="date != null">
                    AND b.date = #{date}
                </when>
                <otherwise>
                    b.`status` = 1
                </otherwise>
            </choose>
        </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.3、trim(where、set) 标签

    使用 trim 可以定义如何覆盖前缀或者后缀,可以定义where节点、set节点等在有多余字符存在的情况下的前后缀覆盖策略。

    <select id="selectUsers" resultType="com.example.User">
      SELECT *
      FROM user
      <trim prefix="WHERE" prefixOverrides="AND | OR ">
        <if test="name != null">
          AND name = #{name}
        </if>
        <if test="age != null">
          AND age = #{age}
        </if>
        <if test="gender != null">
          AND gender = #{gender}
        </if>
      </trim>
    </select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    说明:

    在语句的FROM子句后面使用了标签来处理WHERE子句中的条件。下面是对标签的几个常用属性的解释:

    1、prefix:指定在元素内容之前添加的字符串,这里是"WHERE",即在WHERE子句之前添加"WHERE"关键字。

    2、prefixOverrides:指定需要从元素内容中移除的字符串,多个字符串使用"|"隔开,这里移除了以"AND"或"OR"开头的内容。

    在 trim 标签中,根据条件判断使用 if 标签来动态生成SQL语句的WHERE子句。if 标签的test属性用于判断条件是否成立,如果条件成立,则会将 if 标签中的内容添加到生成的SQL语句中。

    最终生成的SQL语句将会根据传入的参数动态生成,只在满足条件的情况下添加WHERE子句的条件,如下所示:

    SELECT * FROM user WHERE name = #{name} AND age = #{age}
    
    • 1

    注意,由于使用了 trim 标签,只有在满足条件的情况下才会添加WHERE关键字和相应的条件。

    2.4、foreach 标签

    1、foreach元素的属性

    item: 集合元素迭代时的别名称,该参数为必选项,如果遍历的对象是map,则item为val;

    index: 在list、array中,index为元素的序号索引。但是在Map中,index为遍历元素的key值,该参数为可选项;

    open: 遍历集合时的开始符号,通常与close=")"搭配使用。使用场景IN(),values()时,该参数为可选项;

    separator: 元素之间的分隔符,类比在IN()的时候,separator=“,”,最终所有遍历的元素将会以设定的(,)逗号符号隔开,该参数为可选项;

    close: 遍历集合时的结束符号,通常与open="("搭配使用,该参数为可选项;

    2、collection属性值的三种情况

    2.1、如果传入的参数类型为list时: collection的默认属性值为list,同样可以使用@Param注解自定义name;

    2.2、如果传入的参数类型为array时: collection的默认属性值为array,同样可以使用@Param注解自定义name;

    2.3、如果传入的参数类型为Map时: collection的属性值可为三种情况:1.遍历map.keys;2.遍历map.values;3.遍历map.entrySet();

    3、代码示例

    <select id="getAdjRatio" resultType="java.lang.String">
            SELECT ratio FROM power_forecast_adjust_data a
            LEFT JOIN power_forecast_adjust_info b
            ON a.info_id = b.id
            <where>
                id IN 
                <foreach collection="ids" item="id" open="(" close=")" separator=",">
                    #{id}
                </foreach>
            </where>
    </select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    leetcode面试题之栈与队列
    NAT(网络地址转换)
    刨根问底 Kafka,面试过程真好使
    SpringBoot 通过注解给属性添加校验并返回统一结果
    Flink-处理函数以及TopN运用案例
    TiDB亿级数据亚秒响应查询Dashboard使用
    迷茫了3年:做完这个测试项目,我终于决定辞职
    Vue组件------列表组件设计
    Mysql中日期相关的函数
    互联网大厂技术岗实习/求职经验分享(实习内推+简历+面试+offer)
  • 原文地址:https://blog.csdn.net/KevinChen2019/article/details/138151297