【Mybatis】动态 SQL

动态 SQL

动态 sql 是 Mybatis 的强⼤特性之⼀,能够完成不同条件下不同的 sql 拼接。

<if>标签

前端用户输入时有些选项是非必填的, 那么此时传到后端的参数是不确定的, 比如:

那如果在添加⽤户的时候有不确定的字段传⼊,程序应该如何实现呢?

这个时候就需要使⽤动态标签 来判断了,⽐如添加的时候性别 country 和 city 为⾮必填字段,具体实现如下:

javascript 复制代码
    <insert id="insert" parameterType="com.example.springboot3.model.User">
        insert into userinfo (
              username, phone, email,
              <if test="country != null">
                    country,
              </if>
              <if test="city != null">
                    city,
              </if>
        ) values (
              #{username},#{phone}, #{email},
              <if test="country != null">
                    #{country},
              </if>
              <if test="city != null">
                    #{city},
              </if>
        )
    </insert>

这样当 test 中判断结果为 true 时才会拼接上去.

<trim>标签

上面的插⼊⽤户功能,country 和 city 是选填项,如果所有字段都是选填项,就考虑使⽤ <trim> 标签结合 <if> 标签,对多个字段都采取动态⽣成的⽅式。

<trim>标签中有如下属性:

  • prefix:表示整个语句块,以prefix的值作为前缀
  • suffix:表示整个语句块,以suffix的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前缀
  • suffixOverrides:表示整个语句块要去除掉的后缀
javascript 复制代码
    <insert id="insert" parameterType="com.example.springboot3.model.User">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username != null">
                username,
            </if>
            <if test="phone != null">
                phone,
            </if>
            <if test="email != null">
                email,
            </if>
            <if test="country != null">
                country,
            </if>
            <if test="city != null">
                city,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="username != null">
                #{username},
            </if>
            <if test="phone != null">
                #{phone},
            </if>
            <if test="email != null">
                #{email},
            </if>
            <if test="country != null">
                #{country},
            </if>
            <if test="city != null">
                #{city},
            </if>
        </trim>
    </insert>

在以上 sql 动态解析时,会对 <trim> 部分做如下处理:

  • 基于 prefix 配置,开始部分加上 (
  • 第二个 <trim> 开始部分会加上 values (
  • 基于 suffix 配置,结束部分加上 )
  • 多个 <if> 组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于 suffixOverrides 配置去掉最后⼀个 ,

<where>标签

主要作用: 实现查询中的 where 替换, 可以实现无条件查询.

若存在查询条件会生成 where 的 sql 查询, 并且 where 标签可以去除最前面的 and

如果 where 中的所有参数为空, 那么 where 的 sql 就不会生成, 直接就是无条件查询

比如根据 国家(地区) 或者城市进行搜索, 根据属性做 where 条件查询,国家(地区) 或者城市不为 null 的,作为查询条件。

UserMapper 接口中的方法:

javascript 复制代码
List<User> selectByCondition(String country, String city);

UserMapper.xml 中的实现:

javascript 复制代码
    <select id="selectByCondition" resultType="com.example.springboot3.model.User">
        select * from userinfo
        <where>
            <if test="country != null">
                and country=#{country}
            </if>
            <if test="city != null">
                and city=#{city}
            </if>
        </where>
    </select>

以上<where>标签也可以使⽤ <trim prefix="where" prefixOverrides="and"> 替换。

<set>标签

主要作用: 进行修改操作时, 配合 if 处理非必须传输的参数, 特点是自动去除最后一个 ,

根据传⼊的⽤户对象属性来更新⽤户数据,可以使⽤标签来指定动态内容。

UserMapper 接口中的方法:

javascript 复制代码
int updateById(User user);

UserMapper.xml 中的实现:

javascript 复制代码
    <update id="updateById">
        update userinfo
        <set>
            <if test="username != null">
                username=#{username},
            </if>
            <if test="phone != null">
                phone=#{phone},
            </if>
            <if test="email != null">
                email=#{email},
            </if>
            <if test="country != null">
                country=#{country},
            </if>
            <if test="city != null">
                city=#{city},
            </if>
        </set>
        where id=#{id}
    </update>

<set>标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换。

<foreach>标签

对集合进⾏遍历时可以使⽤该标签。

<foreach>标签有如下属性:

  • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
  • item:遍历时的每⼀个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

比如根据用户 id 删除用户:

UserMapper 接口中的方法:

javascript 复制代码
int deleteByIds(List<Integer> ids);

UserMapper.xml 中的实现:

javascript 复制代码
    <delete id="deleteByIds">
        delete from userinfo where id in
        <foreach collection="ids" open="(" item="item" close=")" separator=",">
            #{item}
        </foreach>
    </delete>

好啦! 以上就是对 Mybatis 动态 SQL 的讲解,希望能帮到你 !
评论区欢迎指正 !

相关推荐
这个DBA有点耶2 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范
星恒随风2 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
Alluxio3 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
数据库急诊室_阿哲6 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋7 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子8 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
Joy T9 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
杨凯凡9 小时前
MySQL 死锁怎么排查?InnoDB 锁等待与 Spring Boot 整事务重试实战
数据库·spring boot·mysql
Aloudata9 小时前
Claude 做数据分析的这两年:一份复盘与发展线索
大数据·数据库·人工智能·数据挖掘·数据分析·dataagent
Decay__9 小时前
01_SQLServer 体系架构全解 —— 实例进程、关系引擎、SQLOS 与事务日志深入
运维·数据库·sql·mysql·架构