MyBatis动态SQL表达式详解

 更新时间:2022年12月29日 10:02  点击:194 作者:一个双子座的Java攻城狮

动态 sql 简单来讲就是我们能通过条件的设置生成不同的 sql,MyBatis 中常用的动态 sql 表达式主要是有五种:

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

if

动态 sql 中最常见的场景是根据条件查询,比如要实现一个查询语句,当不传任何参数时查询所有用户,当传了 id 或者 name 时根据条件进行查询,就可以这样写:

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where 1=1
    <if test="id != null and id!=''">
        and id=#{id}
    </if>
    <if test="name != null and name!=''">
        and name=#{name}
    </if>
</select>

对应的 mapper 接口如下:

public interface UserMapper {
    List<User> selectUserByMap(Map<String,Object> param);
    void updateUser(Map<String,Object> param);
}

对应的 Java 代码如下:

Map<String,String> map=new HashMap<String, String>();
map.put("id","1");
map.put("name","javayz");
List<User> users = mapper.selectUserByMap(map);

当 map 中什么都不传时,sql 语句变为:

select * from user where 1=1

当传了 id 或 name 时,分别执行对应的查询。

choose when otherwise

choose 的使用很像 Java 中的 switch 语法,当满足第一个 when 条件时,就不去看后续的条件,如果条件都不满足,则执行 otherwise:

<select id="selectUserByChoose" parameterType="map" resultType="user">
    select * from user where 1=1
    <choose>
        <when test="id != null">
            and id=#{id}
        </when>
        <when test="name != null">
            and name=#{name}
        </when>
        <otherwise>
            and 1=1
        </otherwise>
    </choose>
</select>

trim where set

还记得前面的语法中都写了 where 1=1 吗,至于为什么这样写,目的在于让语法能顺利执行,以 if 语句为例:如果不写 1=1,语法就会变成下面这样:

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where
    <if test="id != null">
        id=#{id}
    </if>
    <if test="name != null">
        and name=#{name}
    </if>
</select>

这个时候如果满足了第一个 if 条件,那不会有问题,但是如果只满足第二个条件,语句就会变成:

select * from user where and name=?

语法直接报错。

MyBatis 提供了一种标签来代替 1=1 的写法,where 标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user
    <where>
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="name != null">
            and name=#{name}
        </if>
    </where>
</select>

set 的语法和 where 类似,在更新时会用到 set:

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

使用 where 时会用自动去替换掉 and 或者 or,而使用 set 时会动态地在行首插入 SET 关键字,并会删掉额外的逗号。

使用 trim 可以用于去除拼接 sql 时的 and、or 关键字或者逗号等等。

之前使用 where 标签去除了最开始的 and 关键字,用 trim 也同样可以实现:

<select id="selectUserByMap" parameterType="map" resultType="map">
    select * from user
    <trim prefix="where" prefixOverrides="and">
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="name != null">
            and name=#{name}
        </if>
    </trim>
</select>

foreach

foreach 在需要对集合进行遍历的场景中使用很广泛,尤其是在 in 语句中,比如下面这条语句:

select * from user where id in (1,2,3,4)

通过 foreach 实现方式如下,foreach 中的 ids 可以是参数传入的一个 List 集合:

<select id="selectUserByForeach" parameterType="map" resultType="User">
    select * from user where id in
        <foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
            #{id}
        </foreach>
</select>

sql片段

通过 sql 片段标签,可以将重复的 sql 提取出来,使用时通过 include 引用即可。

<sql id="select_user_where">
    <if test="id != null and id!=''">
        and id=#{id}
    </if>
    <if test="name != null and name!=''">
        and name=#{name}
    </if>
</sql>
<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where 1=1
    <include refid="select_user_where">
</select>

到此这篇关于MyBatis动态SQL表达式详解的文章就介绍到这了,更多相关MyBatis动态SQL内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/weixin_64061088/article/details/128450

[!--infotagslink--]

相关文章

  • ps动态环绕动画效果怎么制作

    ps动态环绕动画效果是现在很多人都非常喜欢的,大多数人还不知道ps动态环绕动画效果怎么制作下面文章就给大家介绍下ps怎么制作科技感十足的动态环绕动画效果,一起来看看...2017-07-06
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • Mybatis Plus select 实现只查询部分字段

    这篇文章主要介绍了Mybatis Plus select 实现只查询部分字段的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-01
  • MySQL性能监控软件Nagios的安装及配置教程

    这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
  • PostgreSQL判断字符串是否包含目标字符串的多种方法

    这篇文章主要介绍了PostgreSQL判断字符串是否包含目标字符串的多种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-23
  • 解决Mybatis 大数据量的批量insert问题

    这篇文章主要介绍了解决Mybatis 大数据量的批量insert问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-09
  • vue 实现动态路由的方法

    这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
  • mybatis的Configuration详解

    这篇文章主要介绍了mybatis的Configuration详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-04
  • PostgreSQL TIMESTAMP类型 时间戳操作

    这篇文章主要介绍了PostgreSQL TIMESTAMP类型 时间戳操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-26
  • 详解Mysql中的JSON系列操作函数

    新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
  • PHP正则表达式取双引号内的内容

    取双引号内的内容我们如果一个字符串中只有一个可以使用explode来获得,但如果有多个需要使用正则表达式来提取了,具体的例子如下。 写程序的时候总结一点经验,如何只...2016-11-25
  • mybatis 返回Integer,Double,String等类型的数据操作

    这篇文章主要介绍了mybatis 返回Integer,Double,String等类型的数据操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-11-25
  • postgresql 实现多表关联删除

    这篇文章主要介绍了postgresql 实现多表关联删除操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-02
  • Postgresql 如何选择正确的关闭模式

    这篇文章主要介绍了Postgresl 如何选择正确的关闭模式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-18
  • 深入研究mysql中的varchar和limit(容易被忽略的知识)

    为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15
  • postgresql数据添加两个字段联合唯一的操作

    这篇文章主要介绍了postgresql数据添加两个字段联合唯一的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-04
  • MySQL 字符串拆分操作(含分隔符的字符串截取)

    这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
  • mysql的3种分表方案

    一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
  • Vue实现动态查询规则生成组件

    今天我们来给大家介绍下在Vue开发中我们经常会碰到的一种需求场景,本文主要介绍了Vue动态查询规则生成组件,需要的朋友们下面随着小编来一起学习学习吧...2021-05-27
  • PHP正则表达式之捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同...2015-11-08