Mybatis学习笔记(四) 之动态SQL语句
动态SQL
mybatis 的动态sql语句是基于OGNL表达式的。可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:
1. if 语句 (简单的条件判断)
2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似.
3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)
5. set (主要用于更新时)
6. foreach (在实现 mybatis in 语句查询时特别有用)
1、if 处理
普通带有where查询的语句如下,
<!-- 综合查询 -->
<select id="findUserList" parameterType="User" resultType="User">
select * from `user` where id = #{id} and userName like '%${userName}%'
</select>
此时,如果id或userName为null,此语句查询结果可能报错,那么我们可以对where语句使用逻辑上的if判断:如果值为null或等于空字符串,我们就不进行此条件的判断,增加灵活性。
加入判断之后,如下:
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user where 1=1
<if test="id!=null and id!=''">and id=#{id}
</if>
<if test="username!=null and username!=''">and username like '%${username}%'
</if>
</select>
这条语句查询用户表,如果id或usrname不为null或空,传入userName和id查询条件,那么就查询语句就为:select * from `user` where id = #{id} and userName like '%${userName}%' ;反之,则查询select * from user where 1=1 所有记录。
注意:where语句中加上1=1的目的就是防止 if语句中都不成立情况下,where语句后条件会为空,这样会报错的。如下:如果if条件都不成立,就相当于查询,select * from user where 这是错误的sql语句。
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user where
<if test="id!=null and id!=''">and id=#{id}
</if>
<if test="username!=null and username!=''">and username like '%${username}%'
</if>
</select>
2、choose (when, otherwise)处理
相当于java语言中的switch,有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为true,就会执行if标签中的条件。MyBatis提供了choose 元素。if标签是与(and)的关系,而choose标签是或(or)的关系。
choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose结束,跳出choose,当choose中所有when的条件都不满则时,则执行otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default
<select id="queryByName" parameterType="User" resultType="User">
SELECT <include refid="columns"></include>
FROM sys_user
WHERE user_type_id = 1
<choose>
<when test="userName != null">user_name like '%' #{userName} '%'</when>
<when test="nickName != null">nick_name like '%' #{nickName} '%'</when>
<otherwise>is_valid = 1</otherwise>
</choose>
</select>
3、trim处理
trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
trim 属性
prefix:前缀覆盖并增加其内容
suffix:后缀覆盖并增加其内容
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件
<select id="findUserList" parameterType="User" resultType="User">
select b.* from sys_menu b where where 1=1
<trim suffix="WHERE" suffixOverrides="AND | OR">
<if test="id != null and id !='' "> AND b.id =#{id} </if>
<if test="name != null"> AND b.menu_name like #{name} </if>
</trim>
</select>
最终sql打印为:select b.* from sys_menu b where 1 = 1 AND b.menu_name like '' WHERE
4、foreach处理
传递list实现
当要传入多个id查询时候,比如 :SELECT * FROM USERS WHERE username LIKE '%张%' and id IN (10,89,16),在使用IN查询的时候。
这个时候,就可以使用foreach来传入参数。如果if成立,实现的查询语句就为上面sql语句。
<select id="selectUserByList" parameterType="java.util.List" resultType="user">
select * from user
<where>
<!-- 传递List,List中是pojo -->
<if test="list!=null">
<foreach collection="list" item="item" open="and id in("separator=","close=")">
#{item.id}
</foreach>
</if>
</where>
</select>
传递单个数据(数组中是字符串类型)实现
<!-- 传递数组综合查询用户信息 -->
<select id="selectUserByArray" parameterType="Object[]" resultType="user">
select * from user
<where>
<!-- 传递数组 -->
<if test="array!=null">
<foreach collection="array"index="index"item="item"open="and id in("separator=","close=")">
#{item}
</foreach>
</if>
</where>
</select>
我们知道Mybatis进行SQL映射时,传入参数只能有一个,如果想传入多个参数,只能使用Java的List或是Array进行封装后再传入。上面的语句就是将要删除的多条记录的Id值放在了List对象中传入。
foreach 元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串(上例中的open和close属性)以及在迭代中间放置分隔符(separator属性)。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。
我们可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当我们这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。
参考
1、mybatis系列:http://blog.csdn.net/chris_mao/article/details/48827961
2、动态sql语句:http://limingnihao.iteye.com/blog/782190
Mybatis学习笔记(四) 之动态SQL语句的更多相关文章
- MyBatis学习 之 四、动态SQL语句
有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息.使用Oracle的序列.mysq ...
- mybatis学习笔记四(动态sql)
直接贴图,注解在代码上,其他的配置文件在学习一中就不贴了 1 数据库 2 实体类 package com.home.entity; /** * 此类是: 用户实体类 * @author hpc * @ ...
- MyBatis学习 之 三、动态SQL语句
目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...
- Mybatis学习(8)动态sql语句
Mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类: 1. if 语句 (简单的条件判断) 2. ...
- Mybatis 系列9-强大的动态sql 语句
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- 【转载】 mybatis入门系列四之动态SQL
mybatis 详解(五)------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when, ...
- mybatis学习笔记(四)-- 为实体类定义别名两种方法(基于xml映射)
下面示例在mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现 Demo的基础上进行优化 以新增一个用户为例子,原UserMapper.xml配置如下: < ...
- MyBatis学习(二)、SQL语句映射文件(2)增删改查、参数、缓存
二.SQL语句映射文件(2)增删改查.参数.缓存 2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id=" ...
- MyBatis学习(二)、SQL语句映射文件(1)resultMap
二.SQL语句映射文件(1)resultMap SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyB ...
- MyBatis学习笔记(四)——解决字段名与实体类属性名不相同的冲突
转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4264425.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演 ...
随机推荐
- Guava之简介
1.介绍 Guava最初是在2007年作为“Google Collection Library” 出现的,这个项目在处理Java集合时提供了一些有用的工具,Google的这个guava项目已经成为了 ...
- 安装64位的oracle连接客户端
VS自带的WebServer只有32位的,你只能以32位运行,即使你的VS里面编译目标是64位的, 注意:发布到iis,可以以64位运行,你需要安装64位的oracle连接客户端.如果没有,你的程序必 ...
- 增强型for语句与java,c#的不同之处,with语句的使用
<script type="text/javascript" language="javascript"> //遍历数组 var arr = [&q ...
- Julia语言:让高性能科学计算人人可用
Julia语言:让高性能科学计算人人可用要:一群科学家对现有计算工具感到不满:他们想要一套开源系统,有C的快速,Ruby的动态,Python的通用,R般在统计分析上得心应手,Perl的处理字符串处理, ...
- JavaScript原生数组函数
有趣的JavaScript原生数组函数 在JavaScript中,可以通过两种方式创建数组,构造函数和数组直接量, 其中后者为首选方法.数组对象继承自Object.prototype,对数组执行typ ...
- hadoop集群的搭建与配置(2)
对解压过后的文件进行从命名 把"/usr/hadoop"读权限分配给hadoop用户(非常重要) 配置完之后我们要创建一个tmp文件供以后的使用 然后对我们的hadoop进行配置文 ...
- [转]Intercepting the App Store's Traffic on iOS
Source:https://nabla-c0d3.github.io/blog/2013/08/20/intercepting-the-app-stores-traffic-on-ios/ TL;D ...
- Android简单发送邮件(可带附件)
项目中遇到了一个发送邮件的功能,在网上查了很多,资料也很多.这里就不一一介绍了,只是写出我使用的方案(最简单的) Intent email = new Intent(android.content.I ...
- js中常见的问题
js中常见的问题 原文链接 1.js获取select标签选中的值 原生js var obj = document.getElementByIdx_x(”testSelect”); //定位id var ...
- rcp(插件开发) 如何查找自己定义的扩展点
规则: 扩展点所在的插件ID(X)+扩展点的name(Y) 也就是 X.Y 具体代码 Platform.getExtensionRegistry().getExtensionPoint(X.Y).ge ...