一、动态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用法

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

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

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

测试上述代码,如下

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

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

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

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

三、if+where用法

单表查询,考虑如下代码

  1. <select id="getUserList" resultType="User">
  2. select * from smbms_user where
  3. <if test="userName != null and userName != ''">
  4. u.userName like concat('%', #{userName}, '%')
  5. </if>
  6. <if test="userRole != null">
  7. and u.userRole = #{userRole}
  8. </if>
  9. </select>

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

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

  1. <select id="getUserList" resultType="User">
  2. select * from smbms_user
  3. <where>
  4. <if test="userName != null and userName != ''">
  5. and u.userName like concat('%', #{userName}, '%')
  6. </if>
  7. <if test="userRole != null">
  8. and u.userRole = #{userRole}
  9. </if>
  10. </where>
  11. </select> 

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

四、if+trim用法

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

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

  1. <select id="getUserList" resultType="User">
  2. select * from smbms_user
  3. <trim prefix="where" prefixOverrides="and | or">
  4. <if test="userName != null and userName != ''">
  5. and u.userName like concat('%', #{userName}, '%')
  6. </if>
  7. <if test="userRole != null">
  8. and u.userRole = #{userRole}
  9. </if>
  10. </trim>
  11. </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. C#如何生成setup安装文件

    当前项目状况如图: ,如何把test1打包成setup文件,用户安装后即可完成相应功能. 第一,右击“解决方案test1”->添加“新建项目”->“其他项目类型”->“安装和部署”- ...

  2. python-pyhs2

    #!/usr/bin/env python # -*- coding: utf-8 -*- # hive util with hive server2 """ @auth ...

  3. hadoop+zookeeper+hbase伪分布式安装

    基本安装步骤 安装包下载 从大数据组件下载地址下载以下组件安装包 hadoop-2.6.0-cdh5.6.0.tar.gz hbase-1.0.0-cdh5.6.0.tar.gz zookeeper- ...

  4. redis 持久化 RDB

    https://blog.csdn.net/u010028869/article/details/51792197

  5. tkmybatis逆向工程关于tinyint的玄学问题

    数据库中存储的数据类型是tinyint(1) state tinyint(1) 状态0-未完成:1-待提交:2-待支付:3支付失败: 不为空 tinyint(1)存储的时候会存储下面长度的数字 但是在 ...

  6. Leetcode题目34.在排序数组中查找元素的第一个和最后一个位置(中等)

    题目描述: 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标 ...

  7. Nginx事件管理之ngx_event_core_module模块

    1. 概述 ngx_event_core_module 模块是一个事件类型的模块,它在所有事件模块中的顺序是第一位.它主要完成以下两点任务: 创建连接池(包括读/写事件): 决定究竟使用哪些事件驱动机 ...

  8. leetcode-hard-ListNode-23. Merge k Sorted Lists

    mycode   91.2% # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x ...

  9. DP----鬼畜的数字三角形

    数字三角形 1   洛谷   P1216  数字金字塔 我们可以用 f [ i ] [ j ] 表示从(1,1)出发,到达(i,j)的最大权值和. (i , j)可以由 正上(i - 1 , j)或者 ...

  10. LC 774. Minimize Max Distance to Gas Station 【lock,hard】

    On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...