zoukankan      html  css  js  c++  java
  • MyBatis动态SQL第一篇之实现多条件查询(if、where、trim标签)

    一、动态SQL概述

    以前在使用JDBC操作数据时,如果查询条件特别多,将条件串联成SQL字符串是一件痛苦的事情。通常的解决方法是写很多的if-else条件语句对字符串进行拼接,并确保不能忘了空格或在字段的最后省略逗号。MyBatis使用动态SQL来改善这种情形,动态SQL是基于OGNL的表达式,可方便我们在SQL语句中实现某些逻辑。用于实现动态SQL的元素如下。

    • if:利用if实现简单的条件选择
    • choose(when,otherwise):相当于Java中的switch语句,通常与when和otherwise搭配使用
    • set:解决动态更新语句
    • trim:可以灵活的去除多余的关键字
    • foreach:迭代一个集合,通常用于in条件

    二、if用法

    在查询条件不是很多并且较为固定的情况下,最好的解决方案是采用多参数直接入参的方式,这样代码比较清晰,可读性强。如下

    public interface UserMappper{
        public List<User> getUserList(@Param("userName") String userName,
                                      @Param("userRole") Integer roleId);
    }
    <select id="getUserList" resultMap="userList">
      select u.*, r.roleName from smbms_user u, smbms_role r
      where u.userName like connect ('%', #{userName}, '%')
      and u.userRole=#{userRole} and u.userRole=r.id
    </select>

    在上述代码中,参数使用了@Param注解,并将参数roleId重命名为userRole

    测试上述代码,如下

    • 在两个条件都给出的情况下,如String userName="孙"; Integer roleId=3,此时会输出正确结果;
    • 若传入的用户角色roleId为空,即只按用户名称进行模糊查询,如String userName="孙"; Integer roleId=null,此时输出的结果不满足需求:没有输入用户角色的情况下,只根据用户名称进行模糊查询的需求;
    • 若传入的用户用户名称userName为“”(空字符串),roleId有值(roleId=3),此时结果是正确的;

    针对上述这种某字段用户输入可能为空的情况,我们使用动态SQL的if元素来实现多条件查询,如下

    <select id="getUserList" resultMap="userList">
      select u.*, r.roleName from smbms_user u, smbms_role r where u.userRole=r.id
        <if test="userRole != null">
          and u.userRole = #{userRole}
        </if>
        <if test="userName != null and userName != ''">
          and u.userName like concat('%', #{userName}, '%')
        </if>
    </select>

    在上述代码中,利用if元素实现简单的条件判断,if元素的test属性表示进入if内需要满足的条件。此时对于String userName="孙"; Integer roleId=null这种情况,输出了正确结果。

    三、if+where用法

    单表查询,考虑如下代码

    <select id="getUserList" resultType="User">
      select * from smbms_user where
        <if test="userName != null and userName != ''">
          u.userName like concat('%', #{userName}, '%')
        </if>
        <if test="userRole != null">
          and u.userRole = #{userRole}
        </if>
    </select>

    此时对于String userName=""; Integer roleId=3这种情况,会报错,因为多了一个“and”。

    针对这种and、where的处理,可使用动态SQL的where元素,where元素主要用来简化SQL语句中的where条件判断,并智能的处理and和or,不必担心多余关键字导致的语法错误。如下

    <select id="getUserList" resultType="User">
      select * from smbms_user
        <where>
          <if test="userName != null and userName != ''">
            and u.userName like concat('%', #{userName}, '%')
          </if>
          <if test="userRole != null">
            and u.userRole = #{userRole}
          </if>
        </where>
    </select> 

    where元素标签会自动标识其标签内是否有返回值,若有,就插入一个where。此外,若该标签返回的内容是以and或者or开头的,会自动剔除。此时对于String userName=""; Integer roleId=3这种情况会正确输出

    四、if+trim用法

    除了where元素之外,还可以使用trim元素来替代where元素,并实现与where元素相同的效果。

    trim元素也会自动识别其标签内是否有返回值,若有返回值,则在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;trim也可把包含内容首部的某些内容覆盖(即忽略),或者把尾部的某些内容覆盖,与之对应的属性是prefixOverrieds和suffixOverrieds。

    <select id="getUserList" resultType="User">
      select * from smbms_user
      <trim prefix="where" prefixOverrides="and | or">
        <if test="userName != null and userName != ''">
          and u.userName like concat('%', #{userName}, '%')
        </if>
        <if test="userRole != null">
          and u.userRole = #{userRole}
        </if>
      </trim>
    </select>

    prefixOverrides:对于trim包含内容的首部进行指定内容的忽略

  • 相关阅读:
    用JAVA发送一个XML格式的HTTP请求
    LR 测试http协议xml格式数据接口
    软件测试术语
    linux学习笔记
    接口测试文章整理
    InputStream只能读取一次的解决办法 C# byte[] 和Stream转换
    zTree更新自定义标签>>>
    C# 各类常见Exception 异常信息
    C# 调用存储过程 Sql Server存储过程 存储过程报错,程序中的try
    SQL Server 2014 清除用户名和密码
  • 原文地址:https://www.cnblogs.com/yanguobin/p/11708254.html
Copyright © 2011-2022 走看看