MyBatis 实现动态 SQL

 MyBatis 中的动态 SQL 就是SQL语句可以根据不同的情况情况来拼接不同的sql。

本文会介绍 xml注解 两种方式的动态SQL实现方式。

XML的实现方式

先创建一个数据表,SQL代码如下:

DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo`  (`id` int(11) NULL DEFAULT NULL,`username` varchar(127) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`gender` tinyint(4) NULL DEFAULT NULL COMMENT '1-男 2-⼥ ',`delete_flag` tinyint(4) NULL DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

数据库表和JAVA对象的对应如下:

 

平时在注册账号时会有一些非必填项,而我们就可以使用 <if> 标签来跟据条件进行动态的SQL语句的添加。

接口定义:

@Mapper
public interface Userinfo {Integer addUserinfo(User user);
}

<if>标签

语法:

<if test = "条件"> 语句块 </if>

如果 test 后面的条件判断结果为 true,那么就将后面的语句块拼接到最终的 SQL 语句中。

XML的实现代码如下:

<insert id="addUserinfo">insert into userinfo(id, username,<if test="gender != null">gender,</if><if test="deleteFlag != null">delete_flag</if>) values (#{id},#{username},<if test="gender != null">#{gender},</if><if test="deleteFlag != null">#{deleteFlag}</if>);
</insert>

注意:test中的gender和deleteFlag,是传入对象中的属性,不是数据库字段。

执行以下测试代码:

@Test
void addUserinfo() {User user = new User();user.setId(2);user.setUsername("zhangsan");user.setDeleteFlag(0);//此时gender为空userinfo.addUserinfo(user);
}

运行之后我们从日志中可以看出最终执行的SQL语句中并没有 gender

而当我们令gender不为空:

user.setGender(1);

但是此时我们的代码还有一个隐藏BUG,比如当deleteFlag为空时:

@Test
void addUserinfo() {User user = new User();user.setId(2);user.setUsername("zhangsan");//user.setDeleteFlag(0);user.setGender(1);//此时deleteFlag为空userinfo.addUserinfo(user);
}

此时代码报错了,我们可以从MyBatis打印的日志中看出SQL语句出现了多余的逗号。

此时就需要使用<trim>标签

<trim>标签

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

  • prefix:表示在整个语句块起始位置加上prefix的值作为前缀
  • suffix:表示在整个语句块结尾加上suffix的值作为后缀
  • prefixOverrides:如果整个语句块的前缀等于prefixOverrides的值,去掉prefixOverrides的值;
  • suffixOverrides:如果整个语句块的后缀等于suffixOverrides的值,去掉suffixOverrides的值。

我们利用<trim>标签来将上述SQL中结尾的 ‘,’ 去除

<insert id="addUserinfo">insert into userinfo <trim prefix="(" suffix=")" suffixOverrides=",">id, username,<if test="gender != null">gender,</if><if test="deleteFlag != null">delete_flag</if></trim>values<trim prefix="(" suffix=");" suffixOverrides=",">    #{id},#{username},<if test="gender != null">#{gender},</if><if test="deleteFlag != null">#{deleteFlag}</if></trim>
</insert>

此时程序就可以正常执行了。

<where>标签

<where>标签一般应用于需要动态组装where条件的地方。

<where> 只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或
OR。

例如:我们此时根据 id 和 gender 来查找数据。

数据库中的数据如下:

接口定义:

User selectUser(Integer id, Integer gender);

xml实现:

<select id="selectUser" resultType="com.example.Spring_demo.mySQL.User">select * from userinfo<where><if test="id != null">id=#{id}</if><if test="gender != null">and gender=#{gender}</if></where>;
</select>

JAVA测试代码

@Test
void selectUser() {System.out.println(userinfo.selectUser(1, 1));
}

从打印的结果和日志中我们可以看出结果正确。

如果 id 和 gender 都为 null

@Test
void selectUser() {System.out.println(userinfo.selectUser(null, null));
}

虽然程序报错了,可是并不是因为SQL错了而是因为接收的参数报错。

此时可以看出 where 被去掉了。 

此时如果 gender 为空

@Test
void selectUser() {System.out.println(userinfo.selectUser(1, null));
}

<where>标签并不能去除句末的 and 

<set>标签

<set>标签用于动态更新数据

用于 update 语句中动态的在SQL语句中插入 set 关键字,并会删掉额外的逗号。

例如:根据传入的id属性,修改 username 和 gender 中不为null的属性。

接口定义:

Integer upData(Integer id, String username, Integer gender);

xml代码实现:

<update id="upData">update userinfo  <set><if test="username != null">username = #{username},</if><if test="gender != null">gender = #{gender}</if></set>where id = #{id};
</update>

JAVA测试代码

void upData() {//gender为空userinfo.upData(2, "xiaohong", null);
}


可以看出删掉了额外的逗号(前后都会删掉)。

<foreach>标签

该标签可以在对集合进行遍历时使用。

标签有如下属性:

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

例如:批量删除数据

接口定义:

Integer deleteUsers(List<Integer> ids);

xml代码实现:

<delete id="deleteUsers">delete from userinfo where id in<foreach collection="ids" item="id" open="(" close=");" separator=",">#{id}</foreach>
</delete>

注意:这两个地方的名称必须相同。

JAVA测试代码

@Test
void deleteUsers() {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);userinfo.deleteUsers(list);
}

<include>和<SQL>标签

这两个标签配合使用可以实现对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个SQL片段,然后再通过<include> 标签进行引用。用来降低代码的冗余度。

  • <sql> :定义可重用的SQL片段
  • <include> :通过属性refid,指定包含的SQL片段

例如:我们可以抽取下面xml中的部分代码。

<delete id="deleteUsers">delete from userinfo where id in<foreach collection="ids" item="id" open="(" close=");" separator=",">#{id}</foreach>
</delete>
<sql id="aaa">delete from userinfo where id in
</sql><delete id="deleteUsers"><include refid="aaa"></include><foreach collection="ids" item="id" open="(" close=");" separator=",">#{id}</foreach>
</delete>

 JAVA测试代码

@Test
void deleteUsers() {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);userinfo.deleteUsers(list);
}

@注解的实现方式

注解的实现其实非常简单只需把xml标签中的SQL(包括标签),使用<script></script> 标签括起来就可以了。

例如下面的xml代码

<insert id="insertUserByCondition">
INSERT INTO userinfo (
username,
`password`,
age,
<if test="gender != null">
gender,
</if>
phone)
VALUES (
#{username},
#{age},
<if test="gender != null">
#{gender},
</if>
#{phone})
</insert>

注解的实现方法:

@Insert("<script>" +"INSERT INTO userinfo (username,`password`,age," +"<if test='gender!=null'>gender,</if>" +"phone)" +"VALUES(#{username},#{age}," +"<if test='gender!=null'>#{gender},</if>" +"#{phone})"+"</script>")
Integer insertUserByCondition(UserInfo userInfo);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/676033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac上几款好用的MacBook视频播放器

使用Mac电脑时&#xff0c;视频播放器可以说是我们使用频率最高的软件之一了&#xff0c;不管是工作时看视频资料还是在家里看下载好的电影&#xff0c;都需要用到视频播放器&#xff0c;本文中我们就来推荐几款好用的Macbook视频播放器&#xff0c;总有一款适合你&#xff01;…

数据结构——B/顺序表和链表

&#x1f308;个人主页&#xff1a;慢了半拍 &#x1f525; 创作专栏&#xff1a;《史上最强算法分析》 | 《无味生》 |《史上最强C语言讲解》 | 《史上最强C练习解析》 &#x1f3c6;我的格言&#xff1a;一切只是时间问题。 ​ 1.线性表 线性表&#xff08;linear list&…

QXlsx Qt操作excel(1)

QXlsx 是一个用于处理Excel文件的开源C库。它允许你在你的C应用程序中读取和写入Microsoft Excel文件&#xff08;.xlsx格式&#xff09;。该库支持多种操作&#xff0c;包括创建新的工作簿、读取和写入单元格数据、格式化单元格、以及其他与Excel文件相关的功能。 关于QXlsx的…

SQL拆分字段内容(含分隔符)

问题描述&#xff1a; 在做数据迁移的过程中&#xff0c;我们希望对表中的某个字段根据分隔符进行拆分&#xff0c;得到多条数据&#xff0c;原代码有点意思&#xff0c;因此记录一下。 我们假设某条数据如下&#xff1a; IDSTRS1公司名称不能小于四个字&#xff0c;行业类别…

【OrangePi Zero2的系统移植】OrangePi Zero2 SDK说明

一、使用环境要求 二、获取Linux SDK 三、首次编译完整SDK 基于OrangePi Zero2的系统移植 之前我们讲解香橙派的使用时&#xff0c; 都是直接在香橙派上进行代码编译&#xff0c; 但在实际的项目开发过程中&#xff0c;更多 的还是使用交叉编译环境进行代码的编译。再编译完成…

卷积层Conv1d包含的元素分别是什么,经过卷积层,数据的形状发生变化吗?

nn.Conv1d 是一个一维卷积层&#xff0c;它通常用于处理序列数据&#xff0c;如时间序列或文本数据。这个层包含以下主要元素&#xff1a; 输入通道数&#xff08;In_channels&#xff09;&#xff1a;这是输入数据的通道数。对于单通道数据&#xff08;如灰度图像或单变量时间…

医学三基答案在哪搜?4个大学生必备的搜题 #知识分享#职场发展

今天&#xff0c;我将分享一些受欢迎的、被大学生广泛使用的日常学习工具&#xff0c;希望能给你的学习生活带来一些便利和启发。 1.颐博咨询 这是一个网站 找题好用的在线搜题站,快考不限次搜题助手,问题截图搜题软件,练题通关考试试题大全。 2.题小聪 这是一个公众号 这…

macbookair怎么清理内存 ?如何利用 CleanMyMac X 进行系统清理

macbookair怎么清理内存 清理MacBook Air的内存可以通过以下几种方法&#xff1a; 优化储存空间。在MacBook Air上&#xff0c;可以通过“优化储存空间”来释放空间。这包括将文件储存在iCloud中&#xff0c;如桌面、文稿和iCloud信息&#xff0c;以及自动移除在iCloud中观看…

CSP-202203-1-未初始化警告

CSP-202203-1-未初始化警告 难点&#xff1a;时间复杂度 【核心】&#xff1a;统计输入的k组“赋值”中&#xff0c;右值不为0且未在先前作为左值出现过的次数【坑!】本题直接通过暴力枚举时间复杂度很可能过不了 【90分思路】 定义数组 initialized 用来存储已经处理过的左…

从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder &#xff0c;其中 inorder 是二叉树的中序遍历&#xff0c; postorder 是同一棵树的后序遍历&#xff0c;请你构造并返回这颗 二叉树 。 示例 1: 输入&#xff1a;inorder [9,3,15,20,7], postorder [9,15,7,20,3] 输出&#xff1a;[3…

Flink CDC 与 Kafka 集成:Snapshot 还是 Changelog?Upsert Kafka 还是 Kafka?

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,京东购书链接:https://item.jd.com/12677623.html,扫描左侧二维…

MySQL-SQL优化

文章目录 1. SQL性能分析1.1 SQL执行频率1.2 慢查询日志1.3 profile详情1.4 explain 2. SQL优化2.1 Insert 优化2.2 Group By 优化2.3 Order By 优化2.4 Limit 优化2.5 Count() 优化2.6 Update 优化 3. 拓展3.1 请你说一下MySQL中的性能调优的方法&#xff1f;3.2 执行 SQL 响应…

堆的概念实现

前言 本文将详细讲解堆。堆是一种二叉树&#xff08;一般是完全二叉树&#xff09;使用顺序结构的数组来存储。 tip&#xff1a;这里我们需要注意区分堆在不同地方的含义&#xff0c;这里的堆是一个数据结构&#xff0c;操作系统虚拟进程地址空间的堆是操作系统中管理内存的一块…

kubernetes镜像仓库harbor

一、镜像仓库的种类 GitHub GitHub有付费版和免费版,目前默认的docker镜像拉取策略是从GitHub上进行拉取gitee 国内harbor私有仓库二、harbor仓库规划设计 私有镜像仓库 Harbor 安装和配置 新创建一台虚拟机安装harbor, 配置如下: 主机名ip配置网络harbor192.168.1.204VCPU/…

「深度学习」长短时记忆网络LSTM

一、经典模型 \widetilde{c}^{<t>} tanh(w_{c}[a^{<t-1>},x^{<t>}]b_{c}) 更新门&#xff1a;\Gamma_{u} \sigma(w_{u}[a^{<t-1>},x^{<t>}]b_{u}) 遗忘门&#xff1a;\Gamma_{f} \sigma(w_{f}[a^{<t-1>},x^{<t>}]b_{f}) 输出门…

svg 进阶

svg 进阶 svg 应用场景 绘制 icon绘制动画 svg viewport 和 viewBox viewport 是 svg 图像的可见区域 viewBox 是用于在画布上绘制 svg 图形的坐标系统 在一下案例中 svg中 width“500” height“200” 就是可视区域 比如你的svg是100X100但是你的可视区域只有20X20 那么他…

职业性格测试在求职应聘跳槽中的应用

人的性格总是千奇百怪&#xff0c;有的人总是想迎接挑战&#xff0c;超越自己&#xff0c;不停的奔着高处走&#xff0c;然而有的人总是喜欢随遇而安&#xff0c;踏踏实实一辈子&#xff0c;有份安稳的工作&#xff0c;有吃有喝就好。那么对于哪些喜欢迎接挑战&#xff0c;但又…

《MySQL 简易速速上手小册》第4章:数据安全性管理(2024 最新版)

文章目录 4.1 用户认证和权限控制4.1.1 基础知识4.1.2 重点案例&#xff1a;使用 Python 管理 MySQL 用户权限4.1.3 拓展案例 4.2 防止 SQL 注入和其他安全威胁4.2.1 基础知识4.2.2 重点案例&#xff1a;使用 Python 和 MySQL 进行安全的数据查询4.2.3 拓展案例 4.3 数据加密和…

边缘人工智能的发展 —— 边缘AI图形化开发

1、背景 边缘人工智能是指直接在边缘设备上运行的机器学习算法的形式使用人工智能。这里的“边缘设备”指的是网络边缘的设备&#xff0c;例如智能手机、传感器、工业机器人等。这些设备具备数据处理和机器学习算法运行的能力&#xff0c;可以在本地进行必要的数据操作并发送&…

Android Studio无法安装Git问题解决(折中方案)

安装配置好studio&#xff0c;往往会使用git克隆github上面的项目&#xff0c;但是却发现git无法正确安装&#xff0c;本文将介绍如何解决git无法安装这一问题。 对于git安装&#xff0c;实际比较复杂&#xff0c;可以参考这一篇博客。 Git 详细安装教程&#xff08;详解 Gi…