MyBatis动态SQL指南

动态SQL是MyBatis中一个强大的特性。

在JDBC代码中根据不同的条件拼写SQL语句是一件痛苦的事情,而且还容易出错。借助功能强大的基于 OGNL 的表达式,MyBatis的动态SQL在可以让你清晰高效地构建你的SQL语句,提升幸福感。

MyBatis3的常用标签主要有以下几种:

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

一起来看看怎么使用吧!

if where

这两个是我们最常用的标签语句,where语句根据条件来判断是否要包含if标签语句下的内容

select * from user
where age = 12
<if test="name != null">
    and name = #{name}
</if>

这里如果用户传了非空的name值,就可以根据age和name两个条件来查询,不传的话默认就只根据age = 12这个条件来查询,如果还需要其他的条件语句,在下面继续添加即可

select * from user
where age = 12
<if test="name != null">
    and name = #{name}
</if>
<if test="sex != null">
    and sex = #{sex}
</if>

使用where标签对SQL进行智能预处理

如果where语句中没有age = 12这个默认条件

select * from user
where
<if test="name != null">
    and name = #{name}
</if>
<if test="age != null">
    and age = #{age}
</if>

这时用户不传name和age值,最终生成的SQL语句会像这样

select * from user
where

这显然不符合SQL语法规范,会报错的
在这里插入图片描述
如果传了name,SQL又会变成下面这样

select * from user
where and name = 'pname'

依然会报错
在这里插入图片描述

其实我们只要使用where标签语句就可以解决以上问题,SQL修改后如下

select * from user
<where>
    <if test="name != null">
        and name = #{name}
    </if>
    <if test="age != null">
        and age = #{age}
    </if>
</where>

where标签语句会判断是否有if子语句满足条件,如果都不满足条件,整个where语句都会被移除,变成下面这样

select * from user

如果传入了name,where标签会判断语句的开头是否为“AND”或者“OR”,如果是会自动去除

select * from user
where name = 'pname'

常见问题

如果传入的对象参数中没有指定的字段,而你又在if语句中使用了该字段

select * from user
<where>
    <if test="nickname != null">
        and name = #{nickname}
    </if>
</where>

传入的User实体中根本没有nickname属性,这时会报以下错误
在这里插入图片描述

choose when otherwise

choose语句可以实现类似我们Java中switch语句的功能,按顺序对when子句进行条件匹配,满足条件就会使用该when标签下的语句

select * from user
<where>
    <choose>
        <when test="name != null">
            and name = #{name}
        </when>
        <when test="age != null">
            and age = #{age}
        </when>
        <otherwise>
            and sex = 'male'
        </otherwise>
    </choose>
</where>

这时会有以下几种情况:

  • 如果只传了name,那么会使用name-when下的条件语句
  • 如果只传了age,那么会使用age-when下的条件语句
  • 如果name和age都没有传,这时会使用otherwise标签下的语句
  • 如果name和age都传了,这时按照顺序,name-when子句满足条件,将直接使用该标签下的语句,不会再继续向下判断age-when子句了

注意:choose标签语句也要放在where标签下,否则也会出现跟上面if语句一样的问题

trim set

set标签主要用来实现动态更新功能的

update user
<set>
    <if test="name != null">name = #{name},</if>
    <if test="age != null">age = #{age},</if>
</set>
where id = #{id}

trim标签的作用

  • 在SQL语句前拼接“where”、“set”和“values(”等前缀
  • 在SQL语句后拼接“)”等后缀
  • 去除SQL中多余的“and”、“or”以及“,”

如何使用trim

trim标签下有四个属性

  • prefix - 在SQL前要拼接的内容
  • prefixOverrides - SQL中要去除的多余的开头内容,如“and”、“or”之类的
  • suffix - 在SQL后要拼接的内容
  • suffixOverrides - SQL中要去除的多余的结尾内容,如多余的“,”
    实现类似where标签的功能
select * from user
<trim prefix="where" prefixOverrides="AND |OR ">
    <if test="name != null">
        and name = #{name}
    </if>
    <if test="age != null">
        and age = #{age}
    </if>
</trim>

实现类似set标签的功能

<update id="updateByPrimaryKeySelective">
    update user
    <trim prefix="set" suffixOverrides=",">
        <if test="name != null">name = #{name},</if>
        <if test="age != null">age = #{age},</if>
    </trim>
    where id = #{id}
</update>

foreach

foreach标签的作用就对集合进行遍历,经常被用来构建IN条件语句
比如我们传入一个字符串集合nameList,然后查询name在这个集合中的User数据

select * from user
<where>
    <if test="nameList != null">
        and name in
        <foreach collection="nameList" open="(" separator="," close=")" item="name">
            #{name}
        </foreach>
    </if>
</where>
  1. collection - 指定集合属性的名称,这里是nameList
  2. open - 指定拼接SQL的开头前缀,这里是“(”
  3. separator - 分隔符,这里是“,”
  4. close - 指定拼接SQL的结束尾缀,这里是“)”
  5. item - 代表当前遍历集合中一个元素,这里是一个name

这样拼接后的语句如下

select * from user WHERE name in ( ? , ? )

foreach标签还有两个属性,index(表示当前迭代的序号)和nullable(表示集合是否可以为空)

其他

bind标签常用来创建一个变量,可以在上下文中使用

select * from user
<where>
    <if test="name != null">
        <bind name="nameLike" value="'%' + name + '%'"/>
        and name like #{nameLike}
    </if>
</where>

注意:bind的value属性中,没有使用#{name}来获取name属性的值,而是直接用name来获取属性值。

本文介绍了MyBatis常用标签的使用方法和注意事项,希望可以帮到你,有问题可以在评论区交流下,欢迎点赞评论关注。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BruceLuX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值