【Mybatis 系列10-结合源码解析mybatis 执行流程】

【Mybatis 系列9-强大的动态sql 语句】

【Mybatis 系列8-结合源码解析select、resultMap的用法】

【Mybatis 系列7-结合源码解析核心CRUD配置及用法】

【Mybatis 系列6-结合源码解析节点配置objectFactory、databaseIdProvider、plugins、mappers】

【Mybatis 系列5-结合源码解析TypeHandler】

【Mybatis 系列4-结合源码解析节点typeAliases】

【Mybatis 系列3-结合源码解析properties节点和environments节点】

【Mybatis 系列2-配置文件】

【Mybatis 系列1-环境搭建】

上篇系列8中 简单介绍了mybatis的查询,至此,CRUD都已讲完。

本文将介绍mybatis强大的动态SQL。

问题来了: 什么是动态SQL? 动态SQL有什么作用?

传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。

下面就去感受Mybatis动态SQL的魅力吧:

1. if: 你们能判断,我也能判断!

作为程序猿,谁不懂 if ! 在mybatis中也能用 if 啦:

 <select id="findUserById" resultType="user">
select * from user where
<if test="id != null">
id=#{id}
</if>
and deleteFlag=0;
</select>

上面例子: 如果传入的id 不为空, 那么才会SQL才拼接id = #{id}。 这个相信大家看一样就能明白。

细心的人会发现一个问题:“你这不对啊! 要是你传入的id为null, 那么你这最终的SQL语句不就成了 select * from user where and deleteFlag=0, 这语句有问题!”

是啊,这时候,mybatis的 where 标签就该隆重登场啦:

2. where, 有了我,SQL语句拼接条件神马的都是浮云!

咱们通过where改造一下上面的例子:

 <select id="findUserById" resultType="user">
select * from user
<where>
<if test="id != null">
id=#{id}
</if>
and deleteFlag=0;
</where>
</select>

有些人就要问了: “你这都是些什么玩意儿! 跟上面的相比, 不就是多了个where标签嘛! 那这个还会不会出现

select * from user where and deleteFlag=0 ?”

的确,从表面上来看,就是多了个where标签而已, 不过实质上, mybatis是对它做了处理,当它遇到AND或者OR这些,它知道怎么处理。

其实我们可以通过 trim 标签去自定义这种处理规则。

3. trim : 我的地盘,我做主!

上面的where标签,其实用trim 可以表示如下:

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

它的意思就是: 当WHERE后紧随AND或则OR的时候,就去除AND或者OR。

除了WHERE以外, 其实还有一个比较经典的实现,那就是SET。

4. set: 信我,不出错!
 <update id="updateUser" parameterType="com.dy.entity.User">
update user set
<if test="name != null">
name = #{name},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="age != null">
age = #{age}
</if>
<where>
<if test="id != null">
id = #{id}
</if>
and deleteFlag = 0;
</where>
</update>

问题又来了: “如果我只有name不为null, 那么这SQL不就成了

update set name = #{name}, where ........ ?

你那name后面那逗号会导致出错啊!”

是的,这时候,就可以用mybatis为我们提供的set 标签了。下面是通过set标签改造后:

 <update id="updateUser" parameterType="com.dy.entity.User">
update user
<set>
<if test="name != null">name = #{name},</if>
<if test="password != null">password = #{password},</if>
<if test="age != null">age = #{age},</if>
</set>
<where>
<if test="id != null">
id = #{id}
</if>
and deleteFlag = 0;
</where>
</update>

这个用trim 可表示为:

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

WHERE是使用的 prefixOverrides(前缀), SET是使用的 suffixOverrides (后缀), 看明白了吧!

5. foreach: 你有for, 我有foreach, 不要以为就你才屌!

java中有for, 可通过for循环, 同样, mybatis中有foreach, 可通过它实现循环,循环的对象当然主要是java容器和数组。

 <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>

将一个 List 实例或者数组作为参数对象传给 MyBatis,当这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。同样, 当循环的对象为map的时候,index其实就是map的key。

6. choose: 我选择了你,你选择了我!

Java中有switch, mybatis有choose。

 <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>

上例子中: 当title和author都不为null的时候, 那么选择二选一(前者优先), 如果都为null, 那么就选择 otherwise中的, 如果tilte和author只有一个不为null, 那么就选择不为null的那个。 纵观mybatis的动态SQL, 强大而简单, 相信大家简单看一下就能使用了。

下篇文章将结合mybatis的源码分析一次sql语句执行的整个过程。

附:

动态语句参考文章:MySql 动态语句

Mybatis 系列9-强大的动态sql 语句的更多相关文章

  1. 深入浅出Mybatis系列九-强大的动态SQL

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之se ...

  2. MyBatis学习 之 三、动态SQL语句

    目录(?)[-] 三动态SQL语句 selectKey 标签 if标签 if where 的条件判断 if set 的更新语句 if trim代替whereset标签 trim代替set choose ...

  3. MyBatis学习 之 四、动态SQL语句

    有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息.使用Oracle的序列.mysq ...

  4. Mybatis学习(8)动态sql语句

    Mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类: 1. if 语句 (简单的条件判断) 2. ...

  5. mybatis中的动态SQL语句

    有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建 SQL语句. 例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执 ...

  6. 深入浅出Mybatis系列(九)---强大的动态SQL

    上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.resultMap>简单介绍了mybatis的查询,至此,CRUD都已讲完.本文将介绍mybatis ...

  7. 深入浅出Mybatis系列(九)---强大的动态SQL(转载)

    原文出处:http://www.cnblogs.com/dongying/p/4092662.html 上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.r ...

  8. 深入浅出Mybatis系列 强大的动态SQL

    上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.resultMap>简单介绍了mybatis的查询,至此,CRUD都已讲完.本文将介绍mybatis ...

  9. Mybatis学习笔记(四) 之动态SQL语句

    动态SQL mybatis 的动态sql语句是基于OGNL表达式的.可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类: 1. if 语句 (简单的条件 ...

随机推荐

  1. webbrowser 响应关闭事件

    void registerEvents(System.Windows.Forms.WebBrowser web) { var rnd = new Random(); ]; if (head == nu ...

  2. 数学 它的内容,方法和意义 第三卷 (A. D. 亚历山大洛夫 著)

    第十五章 实变数函数论 1. 绪论 2. 集合论 3. 实数 4. 点集 5. 集合的测度 6. 勒贝格积分 第十六章 线性代数 1. 线性代数的对象和它的工具 2. 线性空间 3. 线性方程组 4. ...

  3. mysql数据库优化方法大数据量查询轻松解决

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  4. SpringMVC请求体参数处理问题

    如果请求定义为application/json格式,则要用Spring MVC中@RequestBody参数才能接受(用@RequestParam参数接受会报400错误),但SpringMVC的@Re ...

  5. [转]Spring IOC父子容器简介

    通过HierarchicalBeanFactory接口,Spring的IoC容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的Bean,但父容器不能访问子容器的Bean.在容器内,Bean的 ...

  6. vue-loader v15、vue-loader v14及之前版本,配置css modules的区别

    vue-loader v15 配置css modules: 是在 css-loader 里配置 官方文档:https://vue-loader.vuejs.org/zh/migrating.html# ...

  7. getModifiers 方法解释。

    modifier: 字面意思修饰符. getModifiers  得到的就是 前面的 的修饰符 ,这个方法 字段和方法 都有.这个方法的值是 修饰符 相加的到的值. 例子: public class ...

  8. Linux 命令之删除命令

    在Linux下删除文件用rm命令,具体用法如下: rm [选项] 文件 选项说明: -f -force 忽略不存在的文件,强制删除,无任何提示 -i --interactive 进行交互式地删除 -r ...

  9. JS replace()用法实现replaceAll

    由于js没有提供replaceAll,则使用正则表达式实现全局替换. javascript中replace() 方法如果直接用str.replace("-","!&quo ...

  10. Hive 严格模式与非严格模式

    1. hive严格模式 hive提供了一个严格模式,可以防止用户执行那些可能产生意想不到的不好的效果的查询.即某些查询在严格模式下无法执行.通过设置hive.mapred.mode的值为strict, ...