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>
  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值