MyBatis动态SQL表达式详解

 更新时间:2022年12月27日 11:43:06   作者:一个双子座的Java攻城狮  
动态SQL可以省略很多拼接SQL的步骤,使用类似于JSTL方式,下面这篇文章主要给大家介绍了关于Mybatis动态SQL特性的相关资料,文字通过实例代码介绍的非常详细,需要的朋友可以参考下

动态 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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 快速了解Java中ThreadLocal类

    快速了解Java中ThreadLocal类

    这篇文章主要介绍了快速了解Java中ThreadLocal类,介绍了ThreadLocal 是什么,ThreadLocal的作用,ThreadLocal 原理等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 一篇文章带你理解Java的SPI机制(图文并茂)

    一篇文章带你理解Java的SPI机制(图文并茂)

    本文详细介绍了Java的SPI机制,包括其定义、用途和实现方式,SPI(ServiceProviderInterface)是一种服务发现机制,用于实现框架或库的扩展点,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-10-10
  • 浅析Java中print、printf、println的区别

    浅析Java中print、printf、println的区别

    以下是对Java中print、printf、println的区别进行了详细的分析介绍,需要的朋友可以过来参考下
    2013-08-08
  • MyBatis-Plus联表查询以及分页代码实例

    MyBatis-Plus联表查询以及分页代码实例

    在开发中遇到了一个问题,需要进行联表查询并进行分页,因为不想自己来写分页,所以还是依靠MybatisPlus来实现想要的功能,下面这篇文章主要给大家介绍了关于MyBatis-Plus联表查询以及分页的相关资料,需要的朋友可以参考下
    2023-06-06
  • 详解Java ThreadPoolExecutor的拒绝策略

    详解Java ThreadPoolExecutor的拒绝策略

    这篇文章主要介绍了Java ThreadPoolExecutor的拒绝策略,本文对于线程的池的几种策略进行详细的讲解,在实际的生产中需要集合相关的场景来选择合适的拒绝策略,需要的朋友可以参考下
    2022-08-08
  • 解决Spring Boot 多模块注入访问不到jar包中的Bean问题

    解决Spring Boot 多模块注入访问不到jar包中的Bean问题

    这篇文章主要介绍了解决Spring Boot 多模块注入访问不到jar包中的Bean问题。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Mybatis使用update更新值为null时不生效问题解决

    Mybatis使用update更新值为null时不生效问题解决

    这篇文章主要介绍了Mybatis使用update更新值为null时不生效问题解决,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • MyBatis-Plus枚举和自定义主键ID的实现步骤

    MyBatis-Plus枚举和自定义主键ID的实现步骤

    这篇文章主要给大家介绍了关于MyBatis-Plus枚举和自定义主键ID的相关资料,文中通过实例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-02-02
  • 推荐几款非常实用的IDEA插件小结

    推荐几款非常实用的IDEA插件小结

    这篇文章主要介绍了推荐几款非常实用的IDEA插件小结,解决你开发中可望而又不好找的插件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • SpringBoot注册FilterRegistrationBean相关情况讲解

    SpringBoot注册FilterRegistrationBean相关情况讲解

    这篇文章主要介绍了SpringBoot注册FilterRegistrationBean相关情况,借助FilterRegistrationBean来注册filter,可以避免在web.xml种配置filter这种原始的写法
    2023-02-02

最新评论