动态SQL

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

1. if 语句 (简单的条件判断)
2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似.
3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)
5. set (主要用于更新时)
6. foreach (在实现 mybatis in 语句查询时特别有用)

1、if 处理

普通带有where查询的语句如下,

    <!-- 综合查询 -->
<select id="findUserList" parameterType="User" resultType="User">
select * from `user` where id = #{id} and userName like '%${userName}%'
</select>

此时,如果id或userName为null,此语句查询结果可能报错,那么我们可以对where语句使用逻辑上的if判断:如果值为null或等于空字符串,我们就不进行此条件的判断,增加灵活性。

加入判断之后,如下:

<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user where 1=1
<if test="id!=null and id!=''">and id=#{id}
</if>
<if test="username!=null and username!=''">and username like '%${username}%'
</if>
</select>

这条语句查询用户表,如果id或usrname不为null或空,传入userName和id查询条件,那么就查询语句就为:select * from `user` where id = #{id} and userName like '%${userName}%' ;反之,则查询select * from user where 1=1 所有记录。

注意:where语句中加上1=1的目的就是防止 if语句中都不成立情况下,where语句后条件会为空,这样会报错的。如下:如果if条件都不成立,就相当于查询,select * from user where 这是错误的sql语句。

<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user where
<if test="id!=null and id!=''">and id=#{id}
</if>
<if test="username!=null and username!=''">and username like '%${username}%'
</if>
</select>

2、choose (when, otherwise)处理

相当于java语言中的switch,有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为true,就会执行if标签中的条件。MyBatis提供了choose 元素。if标签是与(and)的关系,而choose标签是或(or)的关系。

choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose结束,跳出choose,当choose中所有when的条件都不满则时,则执行otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default

<select id="queryByName" parameterType="User" resultType="User">
SELECT <include refid="columns"></include>
FROM sys_user
WHERE user_type_id = 1
<choose>
<when test="userName != null">user_name like '%' #{userName} '%'</when>
<when test="nickName != null">nick_name like '%' #{nickName} '%'</when>
<otherwise>is_valid = 1</otherwise>
</choose>
</select>

3、trim处理

trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)

trim 属性

prefix:前缀覆盖并增加其内容

suffix:后缀覆盖并增加其内容

prefixOverrides:前缀判断的条件

suffixOverrides:后缀判断的条件

    <select id="findUserList"  parameterType="User" resultType="User">
select b.* from sys_menu b where where 1=1
<trim suffix="WHERE" suffixOverrides="AND | OR">
<if test="id != null and id !='' "> AND b.id =#{id} </if>
<if test="name != null"> AND b.menu_name like #{name} </if>
</trim>
</select>

最终sql打印为:select b.* from sys_menu b where 1 = 1 AND b.menu_name like '' WHERE

4、foreach处理

传递list实现

当要传入多个id查询时候,比如 :SELECT * FROM USERS WHERE username LIKE '%张%'  and id IN (10,89,16),在使用IN查询的时候。

这个时候,就可以使用foreach来传入参数。如果if成立,实现的查询语句就为上面sql语句。

<select id="selectUserByList" parameterType="java.util.List" resultType="user">
select * from user
<where>
<!-- 传递List,List中是pojo -->
<if test="list!=null">
<foreach collection="list" item="item" open="and id in("separator=","close=")">
#{item.id}
</foreach>
</if>
</where>
</select>

传递单个数据(数组中是字符串类型)实现

<!-- 传递数组综合查询用户信息 -->
<select id="selectUserByArray" parameterType="Object[]" resultType="user">
select * from user
<where>
<!-- 传递数组 -->
<if test="array!=null">
<foreach collection="array"index="index"item="item"open="and id in("separator=","close=")">
#{item}
</foreach>
</if>
</where>
</select>

我们知道Mybatis进行SQL映射时,传入参数只能有一个,如果想传入多个参数,只能使用Java的List或是Array进行封装后再传入。上面的语句就是将要删除的多条记录的Id值放在了List对象中传入。

foreach 元素的功能是非常强大的,它允许你指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许你指定开闭匹配的字符串(上例中的open和close属性)以及在迭代中间放置分隔符(separator属性)。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。

我们可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当我们这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。

参考

1、mybatis系列:http://blog.csdn.net/chris_mao/article/details/48827961

2、动态sql语句:http://limingnihao.iteye.com/blog/782190

Mybatis学习笔记(四) 之动态SQL语句的更多相关文章

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

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

  2. mybatis学习笔记四(动态sql)

    直接贴图,注解在代码上,其他的配置文件在学习一中就不贴了 1 数据库 2 实体类 package com.home.entity; /** * 此类是: 用户实体类 * @author hpc * @ ...

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

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

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

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

  5. Mybatis 系列9-强大的动态sql 语句

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  6. 【转载】 mybatis入门系列四之动态SQL

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

  7. mybatis学习笔记(四)-- 为实体类定义别名两种方法(基于xml映射)

    下面示例在mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现 Demo的基础上进行优化 以新增一个用户为例子,原UserMapper.xml配置如下: < ...

  8. MyBatis学习(二)、SQL语句映射文件(2)增删改查、参数、缓存

    二.SQL语句映射文件(2)增删改查.参数.缓存 2.2 select 一个select 元素非常简单.例如: <!-- 查询学生,根据id --> <select id=" ...

  9. MyBatis学习(二)、SQL语句映射文件(1)resultMap

    二.SQL语句映射文件(1)resultMap SQL 映射XML 文件是所有sql语句放置的地方.需要定义一个workspace,一般定义为对应的接口类的路径.写好SQL语句映射文件后,需要在MyB ...

  10. MyBatis学习笔记(四)——解决字段名与实体类属性名不相同的冲突

    转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4264425.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演 ...

随机推荐

  1. Linux Shell脚本入门--awk命令详解

    简单使用: awk :对于文件中一行行的独处来执行操作 . awk -F :'{print $1,$4}'   :使用‘:’来分割这一行,把这一行的第一第四个域打印出来 . 详细介绍: AWK命令介绍 ...

  2. SSMS2008插件开发(2)--Microsoft Visual Studio 2008插件开发介绍

    原文:SSMS2008插件开发(2)--Microsoft Visual Studio 2008插件开发介绍 由于开发SSMS2008插件是通过VS2008进行的,有必要先介绍一下VS2008的插件开 ...

  3. VS2010新建Web网站与新建Web应用程序的区别

    在Visual Studio 2010中,除了可以使用“创建Web应用程序”的方式来构建自己的Web项目之外,还可以通过创建“Web网站”的方式来构建Web项其中,Web网站的创建方法:打开Visua ...

  4. Oracle汇总笔记

    http://gzf_PC:1158/em数据库配置文件已经安装到 D:\WorkC,同时其他选定的安装组件也已经安装到 D:\WorkC\oracle.iSQL*Plus URL 为:http:// ...

  5. .net图片裁剪抠图之性能优化

    //.net图片裁剪抠图:1.将不坐标点存入GraphicsPath中:GraphicsPath gPath = new GraphicsPath();2. 通常我们判断一个坐标点是否在闭合区间内通采 ...

  6. Android开发方法学

    这是Cyril Mottier最近更新的一篇文章,原谅地址在这里:Android开发方法学. 这篇文章是他介绍自己所在项目小组(Capitaine Train Android Team)设计.开发时的 ...

  7. Manager(管理器)

    Manager(管理器) 索引 意图 结构 参与者 适用性 效果 实现 实现方式(一):Manager 模式的示例实现. 意图 将对一个类的所有对象的管理封装到一个单独的管理器类中. 这使得管理职责的 ...

  8. 附加被分离DB

    如何附加被分离的质疑数据库?   简介 有些时间,由于日志损坏等原因,导致了数据库质疑.如果此时你分离了数据库,那你会发现你无法再附加上数据库,那后果还是很严重的.因此本文提供了一种方式,可以使得当数 ...

  9. Oracle 补丁及opatch 工具介绍

    一. CPU(Critical Patch Update) 一个CPU内包含了对多个安全漏洞的修复,并且也包括相应必需的非安全漏洞的补丁.CPU是累积型的,只要安装最新发布的CPU即可,其中包括之前发 ...

  10. 【转】jQuery each函数中的continue及break

    continue :return true; break :return false; 也可以利用return即可跳出jQuery 来源:http://bie.xiaowangge.info/brow ...