MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情。MyBatis提供了对SQL语句动态的组装能力,而且他只有几个基本的元素,十分简单明了,即大量的判断都可以在MyBatis的映射XML文件里面配置,已达到我们需要大量代码才可以实现的功能。
动态SQL元素
IF元素
IF元素是我们最常用的判断语句,相当于Java中的IF语句。它常常与test属性联合使用。
<select id="findOffice" parameterType="String" resultType="com.mrsaber.model.office">
SELECT * FROM ms_office WHERE 1=1
<if test="ofName != null and ofName!=''">
and of_name = #{ofName}
</if>
</select>
这句话的意思是说,我们把参数ofName传递进入到映射器中,采取构造对ofName的查询。如果这个参数为空,就返回所有的office!通过MyBatis的条件语句我们可以节省许多拼接SQL的工作,把精力集中在XML的维护上。
CHOOSE、WHEN、OTHERWISE元素
IF元素是一种非此即彼的关系,很多时候我们所面的不是一张非此即彼的选择,会有第三种或者更多的选择,也即是说,我们需要类似于SWITCH...CASE....DEFAULT语句,而在映射器中CHOOSE、WHEN、OTHERWISE承担了这个功能。
<select id="findOffice" parameterType="com.mrsaber.model.office" resultType="com.mrsaber.model.office">
SELECT * FROM ms_office
WHERE 1=1
<choose>
<when test="ofName != null and ofName!=''">
AND of_name = #{ofName}
</when>
<when test="ofNo != null and ofNo!=''">
AND of_no = #{ofNo}
</when>
<otherwise>
AND of_addr IS NOT NULL
</otherwise>
</choose>
</select>
这样MyBatis就会根据参数的设置进行判断来动态组装SQL,以满足不同业务的要求。远比Hibernate和JDBC进行大量判断Java代码要清晰和明确的多。
TRIM、WHERE、SET元素
WHERE
上面两组语句我们加入了一个条件“1=1”,如果没有加入这个条件就会变成一个错误语句,即WHERE AND.....
即WHERE后面直接跟上了拼装语句的AND,是不合法的。
但是我们可以用WHERE元素去处理SQL已达到不写该条件的效果。
<select id="findOffice1" parameterType="String" resultType="com.mrsaber.model.office">
SELECT * FROM ms_office
<where>
<if test="ofName != null and ofName!=''">
and of_name = #{ofName}
</if>
</where>
</select>
现在,我们不用再语句中写WHERE 1=1 了,而是加入WHERE元素,系统会自动判断如果条件成立,才会加入WHERE这个SQL关键字到组装的SQL里面,否则不加入。
TRIM
有时我们需要去掉一些特殊的SQL语法,比如常见的and、or。而使用trim元素可以达到我们预期的效果。
<select id="findOffice2" parameterType="String" resultType="com.mrsaber.model.office">
SELECT * FROM ms_office
<trim prefix="WHERE" prefixOverrides="AND">
<if test="ofName != null and ofName!=''">
AND of_name = #{ofName}
</if>
</trim>
</select>
tirm元素意味着我们要去掉一些特殊的字符串,prefix代表的是语句的前缀,而prefixOverrides代表的是你需要去掉的那种字符串,上面写法与WHERE是等效的。
SET
我们需要更新一个对象时,如果我们发送所有的属性去更新一遍,对网络带宽消耗较大,性能最佳的办法是把主键和更新字段的值传递给SQL更新即可。例如office表中有一个主键和两个字段,如果一个个去更新需要写2条SQL,如果有1000个字段呢?显示是不方便的。在MyBatis中,我们常常可以使用set元素来完成这些功能。
也即是说我们如果只更新一个对象的某几个字段时,可以使用SET元素来实现。
<update id="findOffice2" parameterType="com.mrsaber.model.office" >
UPDATE ms_office
<set>
<if test="ofName != null and ofName!=''">
of_name = #{ofName}
</if>
<if test="ofAddr != null and ofAddr!=''">
of_addr = #{ofAddr}
</if>
</set>
where of_No = #{ofNo}
</update>
FOREACH
显然foreach是一个循环语句,它的作用时遍历集合,它能够很好的支持数组、List、Set接口的集合,对此提供遍历的功能。
在数据库中,数据字典是经常使用的内容,比如在用户表中,性别可以分为男、女或者未知,我们把性别作为一个字典,定义如下:
1——男,2——女,0——未知
实际工作中,用户可能查找非未知性别的用户,也可能查找性和未知性别的用户,或者男性和未知性别的用户等,具体的参数需要使用foreach元素去确定。
<select id="findUser" resultType="com.mrsaber.model.user">
SELECT * FROM ms_user WHERE user_sex IN
<foreach collection="sexList" item="sex" index="index" open="(" separator="," close=")">
#{sex}
</foreach>
</select>
说明:
collection配置的sexList是传递进来的参数名称,支持数组、List、Set接口的集合。
item配置的是循环中当前的元素。
index配置的是当期那元素在集合的位置下标。
open和close配置的是以什么符号将这些集合元素包起来。
separator是各个元素的间隔符。
MyBatis:学习笔记(4)——动态SQL的更多相关文章
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- Mybatis学习笔记(六) —— 动态sql
通过mybatis提供的各种标签方法实现动态拼接sql. 需求:根据性别和名字查询用户 查询sql: SELECT id, username, birthday, sex, address FROM ...
- Mybatis学习笔记之---动态sql中标签的使用
动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...
- 1.3(Mybatis学习笔记)动态SQL
一.<if> 使用<if>可以根据具体情况来拼接SQL语句,使其更加灵活更加适应我们的需求. <if>的标签体中是需要拼接的语句,满足条件才会将其进行拼接. < ...
- Mybatis学习笔记14 - 动态sql之foreach标签
一.查询给定集合中员工id对应的所有员工信息 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import ...
- Mybatis学习笔记10 - 动态sql之if判断
示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import java.util.List; public ...
- Mybatis学习笔记13 - 动态sql之set标签
示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; public interface EmployeeMapp ...
- Mybatis学习笔记12 - 动态sql之choose(when otherwise)标签
choose (when, otherwise):分支选择:带了break的swtich-case 示例代码: 接口定义: package com.mybatis.dao; import com.my ...
- Mybatis学习笔记11 - 动态sql之trim标签
trim标签体中是整个字符串拼串后的结果.prefix="" 前缀: prefix给拼串后的整个字符串加一个前缀prefixOverrides="" 前缀覆盖: ...
随机推荐
- PHP中session详解
SESSION 的数据保存在哪里呢? 当然是在服务器端,但不是保存在内存中,而是保存在文件或数据库中. 默认情况下,PHP.ini 中设置的 SESSION 保存方式是 files(session ...
- vue-router 动态路由匹配
export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld, }, { / ...
- JavaScript对象浅复制
1.概述 Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). 注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面 ...
- linux驱动current,引用当前进程,及task_struct(转)
尽管内核模块不象应用程序一样顺序执行, 内核做的大部分动作是代表一个特定进程的. 内核代码可以引用当前进程, 通过存取全局项 current, 它在 <asm/current.h> 中定义 ...
- STL学习笔记(数值算法)
运用数值算法之前必须先加入头文件<numeric> 加工运算后产生结果 1.对序列进行某种运算 T accumulate(InputIterator beg,InputIterator e ...
- Hadoop datanode无法启动
原因是多次 hadoop namenode -format 导致 datanode 的version 里的Cluster-Id 不一致 这个Cluster-Id的位置在: 自己设置的数据临时文件/ ...
- 在Vue中使用layer.js弹出层插件
layer.js(mobile)是一个小巧方便的弹出层插件,在之前的apicloud项目中被大量使用,但最近对apicloud的IDE.非常不友好的文档和极低的开发效率深感厌烦,决定弃用然后转向Vue ...
- Junit使用教程(三)
四.实例总结 1. 参数化测试 有时一个测试方法,不同的参数值会产生不同的结果,那么我们为了测试全面,会把多个参数值都写出来并一一断言测试,这样有时难免费时费力,这是我们便可以采用参数化测试来解决这个 ...
- cache和内存
CPU与内存 北桥:主桥,主要用来处理高速信号,负责与处理器的联系:CPU通过FSB前端总线来访问内存控制器. 南桥:IO桥,负责IO总线之间的通信,比如PCI总线.SATA.USB等,可以连接光驱. ...
- 快速自检电脑是否被黑客入侵过(Linux版)
前言 严谨地说, Linux只是一个内核, `GNU Linux`才算完整的操作系统, 但在本文里还是用通俗的叫法, 把`Ubuntu`,`Debian`,`RedHat`,`CentOS`,`Arc ...