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包含内容的首部进行指定内容的忽略
MyBatis动态SQL第一篇之实现多条件查询(if、where、trim标签)的更多相关文章
- MyBatis从入门到精通(第4章):MyBatis动态SQL【if、choose 和 where、set、trim】
(第4章):MyBatis动态SQL[if.choose 和 where.set.trim] MyBatis 的强大特性之一便是它的动态 SQL.MyBatis 3.4.6版本采用了功能强大的OGNL ...
- mybatis 动态SQL .2
目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,otherwise) 语句 5.动态SQL:tri ...
- 超全MyBatis动态SQL详解!( 看完SQL爽多了)
MyBatis 令人喜欢的一大特性就是动态 SQL. 在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的. MyBatis 动态 SQL 的出现, 解决了这个麻烦. My ...
- 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 ...
- MyBatis从入门到精通(第4章):MyBatis动态SQL【foreach、bind、OGNL用法】
(第4章):MyBatis动态SQL[foreach.bind.OGNL用法] 4.4 foreach 用法 SQL 语句中有时会使用 IN 关键字,例如 id in (1,2,3).可以使用 ${i ...
- MyBatis动态SQL(使用)整理
MyBatis 令人喜欢的一大特性就是动态 SQL.在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的.MyBatis 动态 SQL 的出现, 解决了这个麻烦. MyBa ...
- 04、MyBatis DynamicSQL(Mybatis动态SQL)
1.动态SQL简介 动态 SQL是MyBatis强大特性之一. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似. MyBatis 采用功能强大的基于 OGNL 的表达式来 ...
- MyBatis 动态SQL(十二)
动态条件查询 以下是我们数据库表 tb_user 的记录: 假设现在有一个需求,就是根据输入的用户年龄和性别,查询用户的记录信息.你可能会说,这太简单了,脑袋里立马蹦出如下的 SQL 语句: SELE ...
- mybatis动态sql总结
前言 平时在开发中,针对动态sql这块目前是薄弱点,自己根据官网在对应项目边测试边写博客,此篇只是为了加深动态sql的熟练度,有不到之处敬请批评指正! 1.if 使用动态 SQL 最常见情景是根据条件 ...
随机推荐
- Qbxt AH d4 && day-6
/* 这两天考试直接呵呵了. 赶脚对qbxt的题目无感. 同时也发现了自己的一些问题. 一些思路题总是自己傻逼的挖个坑跳进去. 这两天场场倒数ORZ. 始终是最弱的.... 然后NOIP光荣三等奖了吧 ...
- Codeforces 385C Bear and Prime Numbers(素数预处理)
Codeforces 385C Bear and Prime Numbers 其实不是多值得记录的一道题,通过快速打素数表,再做前缀和的预处理,使查询的复杂度变为O(1). 但是,我在统计数组中元素出 ...
- MySQL_(Java)【事物操作】使用JDBC模拟银行转账向数据库发起修改请求
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...
- Leetcode题目31.下一个排列(中等)
题目描述: 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外 ...
- Location of Docker images in all Operating Systems (Linux, Windows, Redhat, Mac OS X)
原文:http://www.scmgalaxy.com/tutorials/location-of-dockers-images-in-all-operating-systems/ Location ...
- 备忘录:“#ifdef __cplusplus extern "C" { #endif”的定义
看一些程序的时候老是有“#ifdef __cplusplusextern "C" {#endif”的定义,搞搞清楚是怎么回事: Microsoft-Specific Predefi ...
- HearthBuddy卡组
偶数萨 手打两天已上传说,各位加油 欧洲牧羊人 ### 火元素换艾雅# 职业:萨满祭司# 模式:狂野模式## 2x (2) 图腾魔像 # 2x (2) 大漩涡传送门 # 2x (2 ...
- 自定义application的全局捕获异常实现
package com.loaderman.global; import android.app.Application; import android.os.Environment; import ...
- Android中IntentService与Service
Android中的Service是用于后台服务的,当应用程序被挂到后台的时候,问了保证应用某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不是独 ...
- ACO 蚁群算法(算法流程,TSP例子解析)
算法 计算机 超级计算 高性能 科学探索 1. 算法背景——蚁群的自组织行为特征 高度结构化的组织——虽然蚂蚁的个体行为极其简单,但由个体组成的蚁群却构成高度结构化的社会组织,蚂蚁社会的成员有分工,有 ...