mybatis 动态sql
2017-12-11 22:15
429 查看
很多时候需要根据传入的条件去进行sql的拼接,mybatis提供了几个基本的元素,通过这几个标签在xml文件中就可以实现SQL的动态拼接。
最常使用的几个元素定义如下:
1.if标签
if标签是我们常用的判断语句,相当于Java的if语句,常和test属性联合使用。常见的一个应用场景是多个可选条件的查询,比如说branch表中有name和address两个属性,现在用户可以通过输入name或address部分关键字进行查询,但是可能都输入或只输入一个或都不输入,这种时候就可以通过if语句来根据输入的字符串是否为空来拼接处合适的sql。示例如下:
对应的mapper接口:
这里需要注意的是test中的字符串判空语法是类似于java的,并且其中引用传入的参数不需要加#。最前面的where 1=1为了兼容后面的and避免出现
语法错误。
2.choose when otherwise标签
上面的if语句针对条件成立或不成立进行处理,但有很多时候是需要根据条件的不同而进行不同的处理,类似于java中的switch case default的语法,mybatis的choose when otherwise就是用来实现这样多条件选择的。基本语法如下:
如果其中一个when语句条件满足,则执行其中的逻辑并退出
3.trim where set标签
在上面为了避免语法错误加入了1=1这样的条件,在一条sql里加入这样的判断条件未免让人觉得奇怪,我们可以用where标签对sql进行处理达到不需要这种额外判断条件的目的。
where标签的基本语法:
如果test条件为真,则在sql中加入where关键字,否则就不添加。比如
如果传入的name参数不为空,则sql是
如果传入的name为空,则sql是
trim标签也可以实现上面where标签所做的事情,并且功能更为强大。trim元素有四个属性:prefix,prefixOverrides,suffix,suffixOverrides。
prefix表示在trim包裹的语句前面增加一个前缀
suffix表示在trim包裹的预计后面增加一个后缀
prefixOverrides表示覆盖掉(去掉)trim语句中第一个满足条件的字符串
suffixOverrides表示覆盖掉(去掉)trim语句最后满足条件的字符串
注意如果prefixOverrides和suffixOverrides指定字符串出现在trim包裹语句的中间位置,而不是最前面/最后面则不会被去掉。
如果trim标签中的条件不成立,导致trim包裹的语句为空,则上述属性都不会生效。下面是两个具体例子:
首先还是前面的根据用户输入的name或city进行模糊查询。
这里用prefix添加where前缀 prefixOverrides用来去掉多余的and防止出现语法错误。下面的例子是根据用户的输入来更新name或city,用户可能会同时输入这两个属性,或只会输入其中一个值,需要根据输入动态的构建对应sql。
这里处理的主要是输入的name不为空而输入的city为空的情况下去掉最后的逗号。除了trim标签mybatis还有一个set标签,专门用来处理更新的时候多余逗号的情况,set默认会去掉最后一个逗号,并且还会在sql语句中自动添加set关键字.所以上面的sql也可以写成下面这种形式:
4.foreach元素
foreach标签是一个循环语句,它的作用是遍历集合,它能很好的支持数组 list set接口的集合,对其提供遍历功能。
下面通过批量插入Branch对象来展示基本的用法:
mapper接口定义如下:
对应的映射文件配置如下:
foreach元素的属性主要有 item,index,collection,open,separator,close。
item 表示集合中每一个元素进行迭代时的别名;
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置;
open 表示整个语句以什么开始;
separator表示在每次进行迭代之间以什么符号作为分隔 符;
close 表示整个语句以什么结束。
这里需要注意的是collection属性,它是必填属性,并且随着mapper接口的传参形式的不同而填充的参数也不同
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3.如果传入的参数是多个或单个参数使用@Param进行注释的时候就需要通过@Param中的名字进行引用。
foreach多用于根据传入的list参数拼接in参数或批量参数拼接values参数的情况。
5.test属性
test属性常用于条件判断语句中,用于进行真假的判断.上面已经在if语句中用来判断过字符串是否为空。其实还可以用来判断字符串是否相等,数字大小关系等。字符串相等用”=”,数字的相等用”==”。
6.bind参数
bind参数用来定义一个变量,可以在上下文中使用。比如前面的模糊查询,就可以不使用concat进行字符串的拼接,而是直接给传入的参数加上”%”号,从而直接用来进行查询。示例如下:
最常使用的几个元素定义如下:
语句 | 作用 | 备注 |
---|---|---|
if | 判断语句 | 单条件分支判断 |
choose(when otherwise) | 相当于Java中的case switch | 多条件分支判断 |
trim(where set) | 辅助元素 | 用来处理一些sql拼接问题 |
foreach | 循环语句 | 在in语句等列举条件常用 |
if标签是我们常用的判断语句,相当于Java的if语句,常和test属性联合使用。常见的一个应用场景是多个可选条件的查询,比如说branch表中有name和address两个属性,现在用户可以通过输入name或address部分关键字进行查询,但是可能都输入或只输入一个或都不输入,这种时候就可以通过if语句来根据输入的字符串是否为空来拼接处合适的sql。示例如下:
<select id="getBranchByNameAndCity" resultType="branch"> select * from branch where 1=1 <if test="city!=null and city!=''"> and city like concat('%',#{city},'%') </if> <if test="name!=null and name!=''"> and name like concat('%',#{city},'%') </if> </select>
对应的mapper接口:
public List<Branch> getBranchByNameAndCity(@Param("name") String name, @Param("city") String city);
这里需要注意的是test中的字符串判空语法是类似于java的,并且其中引用传入的参数不需要加#。最前面的where 1=1为了兼容后面的and避免出现
语法错误。
2.choose when otherwise标签
上面的if语句针对条件成立或不成立进行处理,但有很多时候是需要根据条件的不同而进行不同的处理,类似于java中的switch case default的语法,mybatis的choose when otherwise就是用来实现这样多条件选择的。基本语法如下:
<choose> <when test=""> </when> <when test=""> </when> <otherwise> </otherwise> </choose>
如果其中一个when语句条件满足,则执行其中的逻辑并退出
<choose>语句,如果所有
<when>中的条件都不满足,则执行
<otherwise>中的逻辑继续上面的例子,现在假定如果传入name就按name进行匹配,否则就按city就行匹配,如果两者都为空,则将address不为null的记录查询出来。针对这个场景,如果还是使用if那么实现起来就很困难,但是如果使用choose when otherwise实现起来就比较简单:
<select id="getBranchByNameAndCity" resultType="branch"> select * from branch where <choose> <when test="name!=null and name!=''"> name like concat('%',#{name},'%') </when> <when test="city!=null and city!=''"> city like concat('%',#{city},'%') </when> <otherwise> address is not null </otherwise> </choose> </select>
3.trim where set标签
在上面为了避免语法错误加入了1=1这样的条件,在一条sql里加入这样的判断条件未免让人觉得奇怪,我们可以用where标签对sql进行处理达到不需要这种额外判断条件的目的。
where标签的基本语法:
<where> <if test> </if> </where>
如果test条件为真,则在sql中加入where关键字,否则就不添加。比如
<select id="getBranchByNameAndCity" resultType="branch"> select * from branch <where> <if test="name!=null and name!=''"> name like concat('%',#{name},'%') </if> </where> </select>
如果传入的name参数不为空,则sql是
select * from branch WHERE name like concat('%',name,'%')。
如果传入的name为空,则sql是
select * from branch。
trim标签也可以实现上面where标签所做的事情,并且功能更为强大。trim元素有四个属性:prefix,prefixOverrides,suffix,suffixOverrides。
prefix表示在trim包裹的语句前面增加一个前缀
suffix表示在trim包裹的预计后面增加一个后缀
prefixOverrides表示覆盖掉(去掉)trim语句中第一个满足条件的字符串
suffixOverrides表示覆盖掉(去掉)trim语句最后满足条件的字符串
注意如果prefixOverrides和suffixOverrides指定字符串出现在trim包裹语句的中间位置,而不是最前面/最后面则不会被去掉。
如果trim标签中的条件不成立,导致trim包裹的语句为空,则上述属性都不会生效。下面是两个具体例子:
首先还是前面的根据用户输入的name或city进行模糊查询。
<select id="getBranchByNameAndCity" resultType="branch"> select * from branch <trim prefix="where" prefixOverrides="and"> <if test="name!=null and name!=''"> and name like concat('%',#{name},'%') </if> <if test="city!=null and city!= ''"> and city like concat('%',#{name},'%') </if> </trim> </select>
这里用prefix添加where前缀 prefixOverrides用来去掉多余的and防止出现语法错误。下面的例子是根据用户的输入来更新name或city,用户可能会同时输入这两个属性,或只会输入其中一个值,需要根据输入动态的构建对应sql。
<select id="updateBranchInfo" resultType="int"> update branch SET <trim suffixOverrides=","> <if test="name!=null and name!=''"> name =#{name}, </if> <if test="city!=null and city!=city"> city=#{city} </if> </trim> where branch_id=#{id} </select>
这里处理的主要是输入的name不为空而输入的city为空的情况下去掉最后的逗号。除了trim标签mybatis还有一个set标签,专门用来处理更新的时候多余逗号的情况,set默认会去掉最后一个逗号,并且还会在sql语句中自动添加set关键字.所以上面的sql也可以写成下面这种形式:
<update id="updateBranchInfo" > update branch <set> <if test="name!=null and name!=''"> name=#{name}, </if> <if test="city!=null and city!=''"> city=#{city} </if> </set> where branch_id=#{id} </update>
4.foreach元素
foreach标签是一个循环语句,它的作用是遍历集合,它能很好的支持数组 list set接口的集合,对其提供遍历功能。
下面通过批量插入Branch对象来展示基本的用法:
mapper接口定义如下:
public void batchSave(@Param("branchList") List<Branch> branchList);
对应的映射文件配置如下:
<insert id="batchSave"> insert into branch <include refid="insertKey"/> values <foreach item="bc" index="index" collection="branchList" separator=","> ( #{bc.name},#{bc.city},#{bc.state},#{bc.zip}) </foreach> </insert> <sql id="insertKey"> (name,city,state,zip) </sql>
foreach元素的属性主要有 item,index,collection,open,separator,close。
item 表示集合中每一个元素进行迭代时的别名;
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置;
open 表示整个语句以什么开始;
separator表示在每次进行迭代之间以什么符号作为分隔 符;
close 表示整个语句以什么结束。
这里需要注意的是collection属性,它是必填属性,并且随着mapper接口的传参形式的不同而填充的参数也不同
1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3.如果传入的参数是多个或单个参数使用@Param进行注释的时候就需要通过@Param中的名字进行引用。
foreach多用于根据传入的list参数拼接in参数或批量参数拼接values参数的情况。
5.test属性
test属性常用于条件判断语句中,用于进行真假的判断.上面已经在if语句中用来判断过字符串是否为空。其实还可以用来判断字符串是否相等,数字大小关系等。字符串相等用”=”,数字的相等用”==”。
6.bind参数
bind参数用来定义一个变量,可以在上下文中使用。比如前面的模糊查询,就可以不使用concat进行字符串的拼接,而是直接给传入的参数加上”%”号,从而直接用来进行查询。示例如下:
<select id="getBranchByNameAndCity" resultType="branch"> <bind name="name_pattern" value="'%'+name+'%'"/> <bind name="city_pattern" value="'%'+city+'%'"/> select* from branch where name like #{name_pattern} and city like #{city_pattern} </select>
相关文章推荐
- MyBatis中的动态SQL
- mybatis动态SQL标签的用法
- mybatis入门基础(五)----动态SQL
- Mybatis动态sql条件查询中if判断Integer的条件写法
- MyBatis的动态SQL查询-让查询更灵活多变!
- 【MyBatis学习07】动态sql
- mybatis 动态SQL语句
- Mybatis 动态解析sql
- Mybatis第三篇【动态SQL】
- MyBatis动态sql中foreach的简单使用
- MyBatis的动态SQL详解
- Mybatis之动态 SQL
- MyBatis(三)配置文件,输入输出映射,动态SQL
- mybatis 动态sql
- 设置在控制台打印 MyBatis 动态生成 SQL 语句的方法
- MyBatis基础:MyBatis动态SQL(3)
- 详解MyBatis的动态SQL
- MyBatis动态SQL小tips
- 一双跑鞋的mybatis(四)---动态sql语句
- ssm的mybatis的动态SQL语句