MyBatis进阶使用——动态SQL
MyBatis的强大特性之一就是它的动态SQL。如果你有使用JDBC或者其他类似框架的经验,你一定会体会到根据不同条件拼接SQL语句的痛苦。然而利用动态SQL这一特性可以彻底摆脱这一痛苦
MyBatis精简了元素种类,在MyBatis3中,我们只需要学习以下4种元素:
- if
- choose(when,otherwise)
- trim(where,set)
- foreach
if
动态SQL通常要做的事情就是根据条件包含where子句的一部分,比如:
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
这条语句提供了一种可选的查找文本功能。如果没有传入“title”,那么就返回所有处于“ACTIVE”状态的博文。反之则还要进行根据“title”参数的模糊查找。
在一个标签中,可以如上面例子一般,嵌套多个if元素。
choose, when, otherwise
如果我们不想应用所有的条件语句而是像switch语句一般进行选择的话,那么我们就应该使用choose元素。
修改上面那个例子,如果存在“title”参数则按照“title”查找,如果提供了“author”参数就按照“author”查找。如果两者都没有提供就返回所有符合条件的博文。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
trim , where , set
那么我们现在希望将所有的where子句的条件都变成动态SQL,可能会编写出这样的代码:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
然而如果这些条件一个都没有匹配上的话,结果SQL语句很可能会变成这样:
SELECT * FROM BLOG
WHERE
如果只有第二个匹配上的话,会变成这样:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
这些查询都会失败,为了解决这个问题,MyBatis有一个简单的解决方案:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
where元素只有在至少一个子元素的条件返回SQL子句的情况下才插入“WHERE”子句。而且若语句的开头为AND或者OR也会将它们去除。
如果希望定制where的行为,我们可以通过自定义trim元素来定制where元素的功能。比如和where元素等价的自定义trim元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
类似的用于动态更新语句的解决方案叫做set。set元素可以用于动态包含所需要更新的列,而舍弃其他。比如:
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
这里set元素会动态前置SET关键字同时删除无关的逗号。
foreach
动态SQL的另外一个常用的操作需求就是对一个集合进行遍历通常是在构建IN条件语句的时候,比如:
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach元素的功能非常强大,它袁旭你指定一个集合,声明可以在元素体内使用的集合项和索引变量。也允许你指定开头和结尾的字符串以及在迭代结果之间放置分隔符。
注意: 我们可以使用任何可迭代对象传递给foreach作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,itme是本次迭代获取的元素。当使用Map对象时,index是键,item是值。
MyBatis进阶使用——动态SQL的更多相关文章
- 【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...
- Mybatis入门之动态sql
Mybatis入门之动态sql 通过mybatis提供的各种标签方法实现动态拼接sql. 1.if.where.sql.include标签(条件.sql片段) <sql id="sel ...
- mybatis 详解------动态SQL
mybatis 详解------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...
- mybatis中的动态SQL
在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...
- Mybatis映射文件动态SQL语句-01
因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...
- 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)
动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的拼接和组装.可以简单的说成Mybatis中可以动态去的判断需不需要某些 ...
- MyBatis注解配置动态SQL
MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...
- mybatis框架(5)---动态sql
那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态S ...
- mybatis教程4(动态SQL)
动态SQL语句 MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空 ...
随机推荐
- 吴恩达机器学习笔记37-学习曲线(Learning Curves)
学习曲线就是一种很好的工具,我经常使用学习曲线来判断某一个学习算法是否处于偏差.方差问题.学习曲线是学习算法的一个很好的合理检验(sanity check).学习曲线是将训练集误差和交叉验证集误差作为 ...
- 微信公众号接入之排序问题小记 Arrays.sort()
微信公众号作为强大的自媒体工具,对接一下是很正常的了.不过这不是本文的方向,本文的方向公众号接入的排序问题. 最近接了一个重构的小项目,需要将原有的php的公众号后台系统,转换为java系统.当然,也 ...
- VS Code 快捷键大全
前言 VSCode的快捷键继承了一些IDE风格,有VS的身影,也有Emacs的身影..简言之,内置快捷键玩熟了,效率提高不是一点两点. VsCode 快捷键有五种组合方式(科普) 通用快捷键 基础编辑 ...
- 阿里云申请ssl证书
申请证书(本文以阿里云服务器为背景,申请证书也以阿里云域名申请证书来作为实例) (1)登陆阿里云服务器,初次配置的用户,不建议直接搜索‘ssl证书’进行购买,因为这样购买后证书与域名对应的引导性并不强 ...
- Saiku多用户使用时数据同步刷新(十七)
Saiku多用户使用时数据同步刷新 这里我们需要了解一下关于saiku的刷新主要有两种数据需要刷新: >1 刷新数据库的表中的数据,得到最新的表数据进行展示. >2 刷新cube信息,得到 ...
- vue 国际化i18n 多语言切换
安装 npm install vue-i18n 新建一个文件夹 i18n ,内新建 en.js zh.js index.js 三个文件 准备翻译信息 en.js export default { ho ...
- 《C++ Primer Plus 第6版》学习笔记
第三章.基本数据类型 整形 short:至少16位 int:至少与short一样长 long:至少32位,且至少与int一样长 long long:至少64位,且至少与long一样长 字符类型 cha ...
- JavaWeb 并发:FOR UPDATE 实战,监测并解决。
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 一.前言 针对并发,老生常谈了.目前一个通用的做法有两种:锁机制:1.悲观锁:2.乐观锁. 但是这篇我 ...
- Servlet & JSP系列文章总结
前言 谢谢大家的捧场,真心感谢我的阅读者. @all 下一期,重点在 数据结构和算法 ,希望给大家带来开心.已经出了几篇,大家爱读就是我的开心. Servlet & JSP系列总结 博客, ...
- two's complement,2的补码
本文为作者原创,允许转载,但必须注明原文地址:https://www.cnblogs.com/byronxie/p/10117265.html Let's start with one questio ...