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 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演 ...
随机推荐
- java基础知识汇总
1. 类的访问控制权限共有两种:public和默认.默认级别的类只能被同一个包中的类看到,包外不可见. 2. 类成员的访问权限共有四种:public,protected,private ...
- C语言内存对齐(2)
前两天参加了360测试实习生的笔试,碰到了一个有关c语言内存对齐的题目,回来后实现了一下,下面是代码: #include <stdio.h> #include <stdlib.h&g ...
- Get Resultset from Oracle Stored procedure
http://stackoverflow.com/questions/1170548/get-resultset-from-oracle-stored-procedure
- js实现在新标签页打开页面
这种方法打开新标签页要在IE9+以上浏览器才可以! <html> <head> <meta http-equiv="Content-type" con ...
- 使用rem设计移动端自适应页面一(转载)
1.困扰多时的问题 在这之前做Web App开发的的时候,在自适应方面一般都是宽度通过百分比,高度以iPhone6跟iPhone5之间的一个平衡值写死,我们的设计稿都是iPhone5的640 * 11 ...
- [转载]Android中WebView自适应屏幕
webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomControls(false); //隐藏webview缩放按钮 让Webview加载的页面居中显示有我知道的 ...
- 动态操作表格行(兼容IE、火狐)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Javascript多线程引擎(六)
Javascript多线程引擎(六) 经过三个月的时间, Javascript 引擎已经完成beta版本(还不支持多线程特性, 预计下个星期就可以支持了, 现阶段还在进行测试基本JS单元功能), 并且 ...
- 跨域访问 REST API
跨域访问 Web Service (REST API) 虽然 JQuery 也能通过授权header实现跨域, 但SharePoint 提供了更简单的方法,它被实现在SP.RequestExecuto ...
- CLR基础之一---认识CLR [《CLR via C#》读书笔记]
<CLR via C#>读书笔记 什么是CLR CLR的基本概念 通用语言运行平台(Common Language Runtime,简称CLR)是微软为他们的.Net虚拟机所选用的名称.这 ...