百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

MyBatis where、set、trim

wptr33 2025-01-10 17:38 19 浏览

1. 前言

在前面的小节中,我们一起学习了 if 标签,在通过 if 判断动态插入或查询的时候容易产生多余的前缀(如 WHERE)或后缀(如 , ),为了解决这类问题 MyBatis 提供了 where、set、trim 三个实用的标签。

其中 where 和 set 标签都是 trim 标签的一种特殊情况,不过使用频率非常高,因此被单独定义成了标签。本小节我们将一起来学习它们。

2. 定义

慕课解释:wheresettrim 三个标签都是为了解决 MyBatis 在动态生成 SQL 时,产生了多余的前缀和后缀的问题。

3. 实例

3.1 where 实例

<select id="selectUserByIdAndName" resultType="com.imooc.mybatis.model.User">
  SELECT * FROM imooc_user
  <where>
    <if test="id != null">
      id = #{id}
    </if>
    <if test="username != null">
      AND username = #{username}
    </if>
  </where>
</select>

在这个例子中,id 和 username 均非固定的过滤参数,只有当其不为 null 时才会加入到 SQL 语句中。此处 where 标签的作用大概有如下 3 个:

  1. 在 id 和 username 都为空的情况下,where 标签不会产生任何 SQL 代码段,最后的 SQL 语句为:SELECT * FROM imooc_user
  2. 在 id 不为空,username 为空的情况下,或者在 id 不为空,username 也不为空的情况下,where 标签会自动给 SQL 代码段添加上 WHERE 前缀;
  3. 在 id 为空,username 不为空的情况下,where 标签会自定去除 AND 前缀,此时生成的 SQL 语句为: SELECT * FROM imooc_user WHERE username = ?

3.2 set 实例

<update id="updateUsernameAndScoreById">
  UPDATE imooc_user
  <set>
    <if test="username != null">
      username = #{username},
    </if>
    id = #{id}
  </set>
  WHERE id = #{id}
</update>

set 标签会自动在 SQL 语句中添加上相应的 SET 前缀,并根据里面的条件动态地添加相应的字段。

由于 SQL update 的语法问题,如 set 标签里面条件均不满足,此时 set 标签也不会添加上 SET 前缀,但此时 SQL 会报语法错误,所以 set 标签中还是得有一个必然存在的赋值。

3.3 trim 实例

<update id="updateUsernameAndScoreById">
  UPDATE imooc_user
  <trim prefix="SET" suffixOverrides=",">
    <if test="username != null">
      username = #{username},
    </if>
    <if test="id != null">
      id = #{id}
    </if>
  </trim>
  WHERE id = #{id}
</update>

这里的 trim 实例实现了与 set 实例同样的功能,set 标签是 trim 标签的一种特殊情况。

trim 标签共有 4 个属性,它们的作用分别如下:

  • prefix: 前缀属性,若标签内不为空则在 SQL 中添加上前缀;
  • prefixOverrides: 前缀覆盖属性,若标签中有多余的前缀,将会被覆盖(其实就是丢弃该前缀);
  • suffix: 后缀属性,若标签内不为空则在 SQL 中添加上后缀;
  • suffixOverrides: 后缀覆盖属性,若标签中有多余的后缀,将会被覆盖(其实就是丢弃该后缀)。

这个例子中,trim 标签的前缀为SET,后缀覆盖属性为,,所以在标签内不为空的情况下给 SQL 语句添加了 SET 关键字,且标签内若有多余的,后缀也会被丢弃。

4. 实践

4.1 例1. 动态插入用户

请使用 MyBatis 完成对 imooc_user 表动态插入用户的功能,若用户属性值不为 null 则插入该字段,否则不插入字段。

分析:

按照 MyBatis 的开发模式,先在 UserMapper.xml 文件中添加动态插入用户的 insert 标签,然后在 UserMapper.java 中添加上对应的方法。

步骤:

首先,在 UserMapper.xml 中添加 insert 标签,并在标签中写入 SQL,使用 trim 标签来动态判断属性是否为空,若不为空则插入该字段。

<insert id="insertUserDynamic" parameterType="com.imooc.mybatis.model.User">
  INSERT INTO imooc_user
  <trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="username != null">
      username,
    </if>
    <if test="age != null">
      age,
    </if>
    <if test="score != null">
      score,
    </if>
  </trim>
  VALUES
  <trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="username != null">
      #{username},
    </if>
    <if test="age != null">
      #{age},
    </if>
    <if test="score != null">
      #{score},
    </if>
  </trim>
</insert>

这里,我们使用了两个 trim 标签,一个用来动态写入字段名,另一个用来动态写入字段值;trim 标签的前缀为(,后缀为),当出现多余的,时,会通过后缀覆盖属性来丢弃。

然后在 UserMapper.java 中添加上对应的接口方法:

package com.imooc.mybatis.mapper;

import org.apache.ibatis.annotations.Mapper;
import com.imooc.mybatis.model.User;

@Mapper
public interface UserMapper {
   int insertUserDynamic(User user);
}

结果:

通过如下代码,我们运行 insertUserDynamic 这个方法。

UserMapper userMapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("dynamic");
user.setScore(100);
int rows = userMapper.insertUserDynamic(user);
System.out.println(rows);

成功后,结果为:

1

TIPS: 注意,在 username、score 和 age 均为 null 时, insertUserDynamic 快报 SQL 语法错误,但理论上若是所有属性均为空,那么也不应该插入。

5. 小结

  • where、set 以及 trim 将 MyBatis 的动态 SQL 发挥到了极致,为开发者节省了大量的精力和时间。
  • trim 标签是 MyBatis 中最为强大的一个标签,使用它可以方便的完成 SQL 动态插入和动态更新。

相关推荐

文科生自学Python-生成简单的WORD文档

--天行健君子以自强不息,地势坤君子以厚德载物,学习编程成就更好的自己--Python语言简洁生动,特别适合文科生学习入门IT世界,用几十行代码就能够做一个完整的爬虫脚本,开发效率杠杠的!短时间内即可...

使用Python 爬取京东、淘宝等商品详情页的数据,避开反爬虫机制

以下是爬取京东商品详情的Python3代码,以excel存放链接的方式批量爬取。excel如下...

CV学习笔记(二十四):数据集标注与制作

最近在做一些数据标注的工作,虽然标注数据比较枯燥,但这也是每个做算法的工程师升级打怪的必由之路。使用一些合适的工具往往可以事半功倍,效率UP。一:数据标注流程二:数据处理的一些小代码1:重命名当得到这...

新手常见的python报错及解决方案(如何理解python报错信息)

此篇文章整理新手编写代码常见的一些错误,有些错误是粗心的错误,但对于新手而已,会折腾很长时间才搞定,所以在此总结下我遇到的一些问题。希望帮助到刚入门的朋友们。后续会不断补充。...

殊途同归python第5节:一键管理所有文档

Python自带的os模块,文件和文件夹的小管家,直接上代码importosa=os.getcwd()#获取当前路径,以字符串形式返回当前的绝对路径。os.chdir("动画片收...

1.文件夹的处理 OS(文件夹的操作方法)

os.getcwd()#当前目录os.listdir()#列出目录下的文件os.path.join()#拼接路径os.path.split()#拆分路径os.path.exists...

Linux下分析bin文件的10种方法(linux binary文件)

这世界有10种人,一种人懂二进制,另一种人不懂二进制。——鲁迅大家好,我是良许。二进制文件是我们几乎每天都需要打交道的文件类型,但很少人知道他们的工作原理。这里所讲的二进制文件,是指一些可执行文件,...

文科生自学Python-pandas交叉透视表降维变换

--心有猛虎,细嗅蔷薇,学习编程成就更好的自己--...

史上最全!近万字梳理Python 开发必备的 os 模块(建议收藏)

点赞、收藏、加关注,下次找我不迷路...

工作中必备的12个Git命令(常用git命令清单)

...

Undoing a git rebase(undoing a git rebase)

技术背景在使用Git进行版本控制时,gitrebase是一个强大的命令,它可以将一个分支的修改合并到另一个分支,使提交历史更加线性。然而,在某些情况下,我们可能需要撤销...

【干货】常用的Git命令有哪些?(git 常用命令行入门)

Git是一个开源的分布式版本控制系统,它被广泛用于软件开发中。在使用Git进行版本控制时,有许多常用的命令,本文将对这些命令进行详细的介绍。...

项目中使用 husky 格式化代码和校验 commit 信息

大家好,我是前端西瓜哥。今天我们学习使用husky工具,在commit的时候做一些风格的校验工作,包括commit信息格式化和文件格式化。githook和husky...

Git可视化极简易教程 — Git GUI使用方法

前言...

实际工作中 Git Commit 代码提交规范是什么样的?

...