一、动态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包含内容的首部进行指定内容的忽略

MyBatis动态SQL第一篇之实现多条件查询(if、where、trim标签)的更多相关文章

  1. MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】

    (第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...

  2. mybatis 动态SQL .2

    目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,otherwise) 语句 5.动态SQL:tri ...

  3. 超全MyBatis动态SQL详解!( 看完SQL爽多了)

    MyBatis 令人喜欢的一大特性就是动态 SQL. 在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的. MyBatis 动态 SQL 的出现, 解决了这个麻烦. My ...

  4. MyBatis动态SQL(认真看看, 以后写SQL就爽多了)

    目录 0 一起来学习 mybatis 1 数据准备 2 if 标签 2.1 在 WHERE 条件中使用 if 标签 2.1.1 查询条件 2.1.2 动态 SQL 2.1.3 测试 2.2 在 UPD ...

  5. MyBatis从入门到精通(第4章):MyBatis动态SQL【foreach、bind、OGNL用法】

    (第4章):MyBatis动态SQL[foreach.bind.OGNL用法] 4.4 foreach 用法 SQL 语句中有时会使用 IN 关键字,例如 id in (1,2,3).可以使用 ${i ...

  6. MyBatis动态SQL(使用)整理

    MyBatis 令人喜欢的一大特性就是动态 SQL.在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的.MyBatis 动态 SQL 的出现, 解决了这个麻烦. MyBa ...

  7. 04、MyBatis DynamicSQL(Mybatis动态SQL)

    1.动态SQL简介 动态 SQL是MyBatis强大特性之一. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似. MyBatis 采用功能强大的基于 OGNL 的表达式来 ...

  8. MyBatis 动态SQL(十二)

    动态条件查询 以下是我们数据库表 tb_user 的记录: 假设现在有一个需求,就是根据输入的用户年龄和性别,查询用户的记录信息.你可能会说,这太简单了,脑袋里立马蹦出如下的 SQL 语句: SELE ...

  9. mybatis动态sql总结

    前言 平时在开发中,针对动态sql这块目前是薄弱点,自己根据官网在对应项目边测试边写博客,此篇只是为了加深动态sql的熟练度,有不到之处敬请批评指正! 1.if 使用动态 SQL 最常见情景是根据条件 ...

随机推荐

  1. TensorFlow使用记录 (七): BN 层及 Dropout 层的使用

    参考:tensorflow中的batch_norm以及tf.control_dependencies和tf.GraphKeys.UPDATE_OPS的探究 1. Batch Normalization ...

  2. BeetleX之快速构建Web多房间聊天室

    其实构建一个Web多房间聊天室也并不是什么困难的技术,借助于websocket就可以轻松实现多用户在线实时通讯交互:在这里主要介绍一下在BeetleX和BeetleXjs的支持下如何让这个功能实现的更 ...

  3. Vue_(组件通讯)使用solt分发内容

    Vue特殊特性slot 传送门 有时候我们需要在自定义组件内书写一些内容,例如: <com-a> <h1>title</h1> </com-a> 如果想 ...

  4. Java中的基本数据类型和引用类型

    一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768 ...

  5. koa 基础(十七)原生 JS 中的类、静态方法、继承

    1.app.js /** * 原生 JS 中的类.静态方法.继承 * es5中的类和静态方法 */ function Person(name, age) { // 构造函数里面的方法和属性 this. ...

  6. cookie、session的联系和区别,多台web服务器如何共享session

    1.Cookie与Session的联系: cookie在客户端保存状态,session在服务器端保存状态.但是由于在服务器端保存状态的时候,在客户端也需要一个标识,所以session也可能要借助coo ...

  7. DP&图论 DAY 2 下午

    DP&图论  DAY 2  下午 基础树形DP 前言◦ 1:与树或图的生成树相关的动态规划.◦ 2:以每棵子树为子结构,在父亲节点合并,注意树具有天然的子结构.这是很优美的很利于dp的.◦ 3 ...

  8. openerp学习笔记 视图中字段只变化(on_change)联动其他字段值、选择和过滤

    1.修改产品数量时,自动计算产品销售金额.销售成本和销售利润<field name="num" on_change="on_change_product(produ ...

  9. JspFragment.invoke方法

    JspFragment.invoke方法可以说是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容.是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出. 例如 ...

  10. Centos7.4 yum 安装MariaDB

    #系统及版本选择:https://downloads.mariadb.org/mariadb/repositories/#mirror=tunavim /etc/yum.repos.d/MariaDB ...