动态 SQL

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。比如:

<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>

choose, when, otherwise

<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

为处理if动态拼接多余的WHERE、AND关键词:

<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 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除,并且插入 prefix 属性中指定的内容。

类似的用于动态更新语句的解决方案叫做 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 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。

若你对等价的自定义 trim 元素的样子感兴趣,那这就应该是它的真面目:

<trim prefix="SET" suffixOverrides=",">
...
</trim>

注意这里我们忽略的是后缀中的值,而又一次附加了前缀中的值。

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是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者Map.Entry对象的集合)时,index是键,item是值。

bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>

Multi-db vendor support

一个配置了“_databaseId”变量的 databaseIdProvider 对于动态代码来说是可用的,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:

<insert id="insert">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
<if test="_databaseId == 'oracle'">
select seq_users.nextval from dual
</if>
<if test="_databaseId == 'db2'">
select nextval for seq_users from sysibm.sysdummy1"
</if>
</selectKey>
insert into users values (#{id}, #{name})
</insert>

动态 SQL 中可插拔的脚本语言

MyBatis 从 3.2 开始支持可插拔的脚本语言,因此你可以在插入一种语言的驱动(language driver)之后来写基于这种语言的动态 SQL 查询。

可以通过实现下面接口的方式来插入一种语言:

public interface LanguageDriver {
ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql);
SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType);
SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);
}

学习mybatis-3 step by step 篇三的更多相关文章

  1. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问

    上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...

  2. Linux 学习 step by step (2)

      Linux 学习 step by step (2) Linux,想要我说爱你真的不容易了,尽管,你是ubutun,尽管,你有蛮界面.但是,操作你,还是没有操作windows那么的如鱼得水了.为了更 ...

  3. MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九

    <Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次   SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...

  4. 【转载】MDX Step by Step 读书笔记(三) - Understanding Tuples (理解元组)

    1. 在 Analysis Service 分析服务中,Cube (多维数据集) 是以一个多维数据空间来呈现的.在Cube 中,每一个纬度的属性层次结构都形成了一个轴.沿着这个轴,在属性层次结构上的每 ...

  5. C# step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型

    C# 2012 step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型 本章内容 声明一个枚举类型 创建并使用一个枚举类型 声明一个结构类型 创建并使用一个结构类型 解释结 ...

  6. 【学习笔记】Baby Step Giant Step算法及其扩展

    1. 引入 Baby Step Giant Step算法(简称BSGS),用于求解形如\(a^x\equiv b\pmod p\)(\(a,b,p\in \mathbb{N}\))的同余方程,即著名的 ...

  7. enode框架step by step之Staged event-driven architecture思想的运用

    enode框架step by step之Staged event-driven architecture思想的运用 enode框架系列step by step文章系列索引: 分享一个基于DDD以及事件 ...

  8. 精通initramfs构建step by step

    (一)hello world  一.initramfs是什么  在2.6版本的linux内核中,都包含一个压缩过的cpio格式 的打包文件.当内核启动时,会从这个打包文件中导出文件到内核的rootfs ...

  9. 稀疏表示step by step(转)

    原文地址:稀疏表示step by step(转)作者:野火春风 稀疏表示step by step(1)     声明:本人属于绝对的新手,刚刚接触“稀疏表示”这个领域.之所以写下以下的若干个连载,是鼓 ...

  10. 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

随机推荐

  1. leadJS初构建

    目录: 1. 面向对象篇 2. 数据结构篇 3. 全局函数篇 4. APICloud篇 1. 面向对象篇 JS原本无法进行程序员世界的面向对象编程,故此对JS封装成一种具有面向对象编程能力的JS. / ...

  2. Linux中Readlink命令

    原文地址:http://blog.csdn.net/liangxiaozhang/article/details/7356829 readlink是Linux系统中一个常用工具,主要用来找出符号链接所 ...

  3. JavaWeb 服务启动时,在后台启动加载一个线程

    JavaWeb 服务启动时,在后台启动加载一个线程. 目前,我所掌握的一共有两种方法,第一种是监听(Listener),第二种是配置随项目启动而启动的Servlet. 下面对这两种方法做一简单的介绍, ...

  4. sklearn_Logistic Regression

    一.什么是逻辑回归? 一种名为“回归”的线性分类器,其本质是由线性回归变化而来的,一种广泛使用于分类问题中的广义回归算法 面试高危问题:Sigmoid函数的公式和性质 Sigmoid函数是一个S型的函 ...

  5. Selenium - Css Selector 使用方法

    什么是Css Selector? Css Selector定位实际就是HTML的Css选择器的标签定位 工具 Css Selector可以下载火狐浏览器插件,FireFinder 或 FireBug和 ...

  6. CentOS系统下的数据盘挂载

    此教程适用系统:Linux(CentOS,Debian,Ubuntu,Fedora) 通常新开通的Linux云服务器数据盘都未做分区和格式化.在进行数据盘挂载之前我们要先进行分区以及格式化操作.注意, ...

  7. linux中vim的常用方法

    i 当前光标位置插入 a 当前光标后插入 0 另起一行插入 A 在光标所在行尾插入 I 在光标所在行首插入 :set nu设置 行号 :set nunu 取消行号 gg 到第一行 G 到最后一行 $ ...

  8. c#获取指定时区的日期

    1.首先将服务器的时间转化为utc时间,然后转换成指定时区的日期 public DateTime GetSpecificZoneNowDate(string zoneName = "Chin ...

  9. java常用功能

    1.复制文件 private void fileChannelCopy(File source, File target) throws IOException { FileInputStream f ...

  10. Go语言初尝

    对于语言设计之争, 唯一需要牢记的一句话是: 如果把 C 变成 C++, 那么 C 就消失了. Go 是一个轻量级的简洁的支持并发的现代语言,  可以用于探索性个人项目, 这是我想学这门语言的主要原因 ...