mybatis动态sql

mybatis的强大特性之一便是它的动态sql。使用过JDBC或其他类似框架的人都会知道,根据不同条件拼接SQL语句时不仅不能忘了必要的空格,还要注意省略掉列名列表最后的逗号,处理方式麻烦且凌乱。mybaits的动态SQL则能让我们摆脱这种痛苦。

以下是mybatis的动态SQL在xml中支持的几种标签。

   if

   choose(when,otherwise)

   trim(where,set)

   foreach

   bind

1、if用法

   <if test="">  </if>

2、choose用法

if标签提供了基本的条件判断,但是它无法实现if...else if ....else....的逻辑,要想实现这样的逻辑,就需要用到choose when otherwise。choose元素中包含when和otherwise两个标签,一个choose中至少有一个when,有0个或者1个otherwise.

select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo,
head_img headImg,
create_time createTime
from sys_user
where 1 = 1
<choose>
   <when test="id != null">
      and id = #{id}
   </when>
   <when test="userName != null and userName != ''">
      and user_name = #{userName}
   </when>
   <otherwise>
      limit 0
   </otherwise>
</choose>

3、where、set、trim用法

这3个标签解决了类似的问题,并且where和set都属于trim的一种具体用法。

3.1 where用法

   如果该标签包含的元素中有返回值,就插入一个where;如果where后面的字符串是以AND和or开头的,就将他们剔除。

select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo,
head_img headImg,
create_time createTime
from sys_user
    <where>
   <if test="userName != null and userName != ''">
      <bind name="userNameLike" value=" '%' +userName+'%'  "/>
      and user_name like #{userNameLike}
   </if>
   <if test="userEmail != '' and userEmail != null">
      and user_email = #{userEmail}
   </if>
 </where>

3.2 set用法

如果该标签包含的元素中有返回值,就插入一个set;如果set后面的字符串是以逗号结尾的,就将这个逗号剔除。

 

update sys_user
<set>
   <if test="userName != null and userName != ''">
      user_name = #{userName},
   </if>
   <if test="userPassword != null and userPassword != ''">
      user_password = #{userPassword},
   </if>
   <if test="userEmail != null and userEmail != ''">
      user_email = #{userEmail},
   </if>
   <if test="userInfo != null and userInfo != ''">
      user_info = #{userInfo},
   </if>
   <if test="headImg != null">
      head_img = #{headImg, jdbcType=BLOB},
   </if>
   <if test="createTime != null">
      create_time = #{createTime, jdbcType=TIMESTAMP},
   </if>
   id = #{id},
</set>
where id = #{id}

3.3 trim用法

where和set标签的功能都可以用trim标签来实现,并且在底层就是通过trimSqlNode实现的。

where标签对应trim的实现如下。

<trim prefix="where" prefixOverrides="and | or"> ....</trim>

set标签对应的trim实现如下。

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

trim标签有如下属性。

 prefix:当trim元素内包含内容时,会给内容增加prefix指定的前缀。

prefixOverrides:当trim元素内包含内容时,会把内容中匹配的前缀字符串去掉。

suffix:当trim元素内包含内容时,会给内容增加suffix指定的后缀。

suffixOverrides:当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉。

4、foreach用法

   SQL语句中有时会使用IN关键字,例如id in(1、2、 3).可以使用$(ids)方式直接获取值,但这种写法不能防止SQL注入,想避免SQL注入就需要用#{}的方式,这时就要配合使用foreach标签来满足需求。

  foreach可以对数组、map或实现了Iterable接口(如List、set)的对象进行遍历。数组在处理时会转换为List对象,因此foreach遍历的对象可以分为两大类:Iterable类型和Map类型。这两种类型的遍历循环时情况不一样。

foreach包含以下属性。

  collection:必填,值为要迭代循环的属性名。这个属性值的情况有很多。

  item:变量名,值为从迭代对象中取出的每一个值。

   index:索引的属性名,在集合数组情况下值为当前索引值,当迭代循环的对象是Map类型时,这个值为Map的key。

  open:整个循环内容开头的字符串。

   close:整个循环内容结尾的字符串。

   separator:每次循环的分隔符。

4.1foreach实现in集合

 

select id,
user_name userName,
user_password userPassword,
user_email userEmail,
user_info userInfo,
head_img headImg,
create_time createTime
from sys_user
where id in
<foreach collection="list" open="(" close=")" separator="," item="id" index="i">
   #{id}
</foreach>

参数是Map类型

使用Map和使用@Param注解方式类似,将collection指定为对应map中的key即可。如果要循环所传入的Map,推荐使用@Param注解指定名字,此时可将collection设置为指定的名字,如果不想指定名字,就使用默认值_parameter

update sys_user
set
<foreach collection="_parameter" item="val" index="key" separator=",">
   ${key} = #{val}
</foreach>
where id = #{id}

5、bind 用法

bind标签可以使用OGNL表达式创建一个变量并将其绑定到上下文中。

例:

   

<if test="userName != null and userName != ''">
   <bind name="userNameLike" value=" '%' +userName+'%'  "/>
   and user_name like #{userNameLike}
</if>

bind标签的两个属性都是必选项,name为绑定到上下文的变量名,value为OGNL表达式。创建一个bind标签的变量后,就可以在下面直接使用,使用bind拼接字符串不仅可以避免因更换数据库而修改SQL,也能预防SQL注入。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值