MyBatis的强大特性之一就是它的动态SQL。如果你有使用JDBC或者其他类似框架的经验,你一定会体会到根据不同条件拼接SQL语句的痛苦。然而利用动态SQL这一特性可以彻底摆脱这一痛苦

MyBatis精简了元素种类,在MyBatis3中,我们只需要学习以下4种元素:

  1. if
  2. choose(when,otherwise)
  3. trim(where,set)
  4. 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的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的动态sql

    最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...

  2. Mybatis入门之动态sql

    Mybatis入门之动态sql 通过mybatis提供的各种标签方法实现动态拼接sql. 1.if.where.sql.include标签(条件.sql片段) <sql id="sel ...

  3. mybatis 详解------动态SQL

    mybatis 详解------动态SQL   目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...

  4. mybatis中的动态SQL

    在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...

  5. 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)

    动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的拼接和组装.可以简单的说成Mybatis中可以动态去的判断需不需要某些 ...

  6. MyBatis注解配置动态SQL

    MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...

  7. mybatis框架(5)---动态sql

    那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态S ...

  8. mybatis教程4(动态SQL)

    动态SQL语句 MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空 ...

  9. mybatis学习 十 动态 SQL

    1.  根据方法传入的参数不同执行不同的 SQL 命令.称为动态 SQL, MyBatis 中动态 SQL 就是在 mapper.xml 中添加逻辑判断等. 2. <if>标签 <s ...

随机推荐

  1. 如何在安装程序中判断操作系统是否是64位 inno

    [Setup]; 开启64位模式ArchitecturesInstallIn64BitMode=x64 [Run] ;根据是否是64位进行不同的操作Filename: "..."; ...

  2. jsp+bean+servlet 案例代码

    包结构图: 代码下载地址

  3. HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

    Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  4. 20151210--MVC

    package com.hanqi; import java.io.IOException; import java.sql.*; import java.text.SimpleDateFormat; ...

  5. C++界面库

    刚开始用C++做界面的时候,根本不知道怎么用简陋的MFC控件做出比较美观的界面,后来就开始逐渐接触到BCG  Xtreme ToolkitPro v15.0.1,Skin++,等界面库,以及一些网友自 ...

  6. 如何生成可变表头的excel(转)

    1.实现功能: 传入一个表头和数据,将数据导入到excel中. 为了便于项目的扩展,数据传入通过泛型集合传入,获取数据时,通过反射的方式获取,这样无论你的表头是多少项,我都能很方便的生成.另外为了便于 ...

  7. jquery中的一点工作小记

    在做一个页面的时候,网页中由许多块相同的地方 ,例如页面中会有多个地方用到TAB 效果,在使用each()遍历以后  不一定会正常显示,这是因为写的html静态页面中只有当前板块中有这个的类,若是用J ...

  8. 浅谈SPA

    最近一直在学习关于Vue的一些知识,由于遇到了问题,去网上查找资料,收获颇丰,在此分享. 1. 什么是SPA? 单页Web应用(single page web application, SPA),就是 ...

  9. x变成y的最少操作次数(层次遍历)

    输入x,y,x为源数字,y为目标值.输出x变成y的最少操作次数. x每次可以执行三种操作:-1 . +1 . x2: 如 x=5,y=8:5-1=4,4x2=8;所以输出结果为2(次操作). 可以发现 ...

  10. 卷积神经网络CNN的意义

    一.选用卷积的原因 局部感知 简单来说,卷积核的大小一般小于输入图像的大小(如果等于则是全连接),因此卷积提取出的特征会更多地关注局部 —— 这很符合日常我们接触到的图像处理.而每个神经元其实没有必要 ...