MyBatis 系列2 -- 增加、删除、修改操作

1. 前言

        上一系列介绍了MyBatis的背景,以及为什么我们使用MyBatis进行操作数据库,还实现了使用MyBatis进行查询数据库的,接下来我们继续将使用MyBatis操作数据库的其他三种基本操作进行总结.

目录

1. 前言

2. 增加用户操作

3. 修改用户操作

4. 删除用户操作

5. 多表查询操作(重点)

5.1 占位符(${} VS #{})

5.2 select标签返回值类型 resultType VS resultMap

5.2.1 resultType

5.2.2 resultMap 

5.2.3 使用别名处理不一致问题

5.3 多表查询

6. 复杂情况:动态SQL使用

6.1 if 标签

6.2 trim标签

6.3 where 标签

6.4 set标签

6.5 foreach标签

总结


2. 增加用户操作

 在UserMapper中实现接口方法add,传入的参数为用户对象,代码如下:

在XML文件中进行构造sql语句,插入操作使用insert标签

不为空的字段必须传值.

这里面进行替换参数的时候我们一般使用#{},有的时候也需要使用${}进行替换.具体后面会详细讲解.

我们接下来为了验证的方便,不在一一写Service层以及Controller层了,我们使用单元测试进行测试我们的代码.

1. 什么是单元测试呢?

 

        单元测试是后端程序人员测试自己小部分代码正确性写的测试代码,当我们最后对称程序进行打包的时候,我们写的单元测试必须全部通过才能打包成功.而且我们的单元测试使用起来很方便,并且不会污染数据库中的数据.

 

SpringBoot项目创建的时候默认会使用单元测试框架spring-boot-test,而这个单元测试框架式依靠另一个注明的测试框架JUnit进行实现的.在pom.xml中就可以看见相关的依赖.

2. 那么如何使用单元测试呢?

2.1 首先我们得生成单元测试的类,在我们要进行测试的类点击generate

 

 

 最终生成的代码

 2.2 给测试类添加注解,表明这个类是用在什么环境下,我们此项目是在SpringBoot项目下,就添加注解SpringBootTest注解

 2.3 在测试方法中进行构造自己的测试代码

2.4 点击运行按钮进行测试 

我们对以上添加操作进行测试,结果如下: 

如果我相反插入用户信息的自增ID,我们需要再xml文件构造sql语句的时候,对id,进行设置.

3.  修改用户操作

还是要按照上述的操作进行,先在UserMapper接口中实现相应的方法,然后在xml文件中使用户Update tablename set where 进行构造sql语句,最后在单元测试中进行测试.

 单元测试结果:

4. 删除用户操作

继续使用上述操作流程,在xml文件中使用delete标签进行构造sql语句.

 单元测试结果:

5. 多表查询操作(重点)

我们之前讲解过了,使用单表查询的操作.但是在实际的工作中并不是操作一张表这么简单的,我们设计到的一定是多表查询.

在总结多表查询之前我们,先把之前残留的一个问题先解决一下.就是占位符问题.

5.1 占位符(${} VS #{})

什么叫预处理编译呢: MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使用 PreparedStatement的 set 方法来赋值。

什么叫字符直接替换呢:MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。

那么问题来了,这两种占位符我们应该怎么使用呢?

 

1. 当我们传入的是一个sql的关键字的时候,考虑使用${};

 

举例: 我们在淘宝中购买商品的时候,可以选择按照类型,价格等进行升序或者降序,那么前端传递给后端的英爱是一个desc或者asc的指令,我们拿到这个指令去进行构造sql语句.这是时候我们必须将该关键字进行替换,才能构造出正确的sql语句,如果使用#{},那么最后select * from userinfo group by id "desc";这样就是一个错误的sql语句了.还有一个关键的思想,我们在使用${}占位符的时候,传入的变量一定得是可预测的,或者说是可以竟枚举的,不然就会引起sql注入的问题.比如我们使用占位符在拼接"select * userinfo where usename =  '${username}' and 'password=${password}'"的时候传入:password的值为' or 1='1,那么最后拼接成的就是:select * userinfo where usename ='张三' and password='' or 1='1'; 那么这个语句就可以获取用户表的所有信息数据,这就及其不安全,所以使用${}一定要考虑sql注入的问题. 

 

2. 在使用like 的时候使用 #{} 报错.

上述进行构造之后: select * from userinfo where username like '%'username'%';

我们此时也不要使用${},我们可以使用MySQL自带的连接函数进行构造:

我们建议还是使用 #{} , 在真正不能使用 #{} 的时候再考虑使用 ${} .

5.2 select标签返回值类型 resultType VS resultMap

在使用select标签的时候,我们必须设置两个参数,id='对应接口方法的名称'  +  返回值类型  

5.2.1 resultType

我们之前设置的返回值类型是resultType,这中方式在绝大数场景下都可以使用到,使用起来很简洁,直接定义到某个实体类.但是当我们的数据库字段名称和程序中字段名称不相同时就访问不到了.

数据库表结构如下:

程序对应如下: 

 

 我们可以很清晰的看出两个密码的字段是不匹配的,当我们还是按照之前的方法进行构造sql 的时候就不可以了

 postman构造请求进行访问:

 此时我们就需要进行使用resultMap了

5.2.2 resultMap 

 

 在xml文件的首部添加

 再进行设置sql语句

 查询结果

5.2.3 使用别名处理不一致问题

字段和属性不一致的简单方案:

书写sql的时候,给不一致的字段使用别名

select id,username as name,password,photo,createtime,updatatime from userinfo

5.3 多表查询

        这一块只使用resultType是不可能将另外一个表的属性进行显示出来的.我们可以使用resultMap将关系进行一一映射,但是使用起来特别麻烦,我们未来的表字段有可能太多,所以不建议使用.

我们使用继承的方式进行实现

1. 我们在model文件夹下创建一个vo目录,用来存放给前端进行展示的类.

2.  实现一个类,继承文章表,并将文章表中没有的作者名字字段添加到新的展示类,并且实现序列化接口Serializable接口.

 我们将返回值类型修改成我们自己的展示类类型

 我们可以看出, 虽然我们继承了父类文章表,但是文章表的属性我们还是没有获取到,这是时候我们就要考虑我们使用的注解了,我们使用了@Data注解,他帮我们重写了tostring方法,我们要看一看这个ToString方法具体是怎么重写的,我们只需要去找到target文件下的Class目录.

我们看看字节码文件是怎么样实现的.

我们看到@Data注解生成的toString方法和我们预期的ToString方法不太一致,它只包含了两个属性,所以我们要自己进行重写toString方法.使其包含父类的属性. 

 最后ToString方法如下:

再进行运行测试代码,就可以得到我们想要的:

6. 复杂情况:动态SQL使用

6.1 if 标签

在注册用户的时候,可能会有这样⼀个问题,如下图所示: 

这个时候就需要使用户动态标签 <if> 来判断了,比如筛选的时候name 和 password为非必填字段,具体实现如下:

 注意test 中的username 和 password 属性,是传入对象的属性名,而不是字段名.

那如果我们进行添加操作呢?

上述进行构造的sql能正常运行,但是如果非必填选项在最后呢?

有可能构造的sql语句为:insert intousername(username,photo,) values("haha","img.png",);这就不行了,是不合法的.所以就有了trim标签.

6.2 trim标签

 改造之后就是:

6.3 where 标签

 直接省略了where关键字,可以将语句中前面的and进行去除

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

6.4 set标签

根据多个参数进行更新数据,可以去除最后面的逗号.

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

6.5 foreach标签

 传入一个集合列表 

 具体的参数对应如下:

总结

        MyBatis的系列到此就结束了,基础的增删改查数据库就是这些内容,后续会根据项目实际使用MyBatis.

希望多多关注,谢谢❤️❤️❤️❤️ 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3. CSS-定位

absolute和relative依据什么定位? relative依据自身定位,absolute 依据最近一层的定位元素定位 (定位元素是指开启了absolute relative fixed的父元素,没有就是根元素body) 居中对齐的实现方式:详情看这篇博客

webpack-theme-color-replacer+elementui自定义配置主题色

webpack-theme-color-replacer原理是通过获取到配置数组里的颜色值&#xff0c;在触发换色方法时&#xff0c;elementui使用的颜色值存在与配置表中颜色一致的颜色&#xff0c;则改颜色会被替换成新的颜色值。 若是自定义的css文件&#xff0c;需要配置css文件路径 若是需要修…

如何应对黑产进行验证图片资源遍历

第一期&#xff0c;我们分享的攻防点是&#xff1a;验证图片资源遍历。 “遍历”指黑产通过穷举法获得所有验证码图片的答案&#xff0c;以便能在未来彻底无视验证码。由于验证码主要是通过图片语义答案来识别人机&#xff0c;因此攻破这层防御最有效的方式就是遍历该验证码图…

【数据结构】二叉树的前中后序遍历(C语言)

文章目录 什么是二叉树树相关的概念树的表示形式特殊的二叉树如何创造出一棵二叉树二叉树的遍历先序遍历(前序遍历)中序遍历后序遍历 总结 什么是二叉树 [二叉树] 顾名思义就是有两个分支节点的树&#xff0c;不仅如此&#xff0c;除了叶子外的所有节点都具有两个分支节点&…

matlab入门

命名规则&#xff1a; clc&#xff1a;清除命令行的所有命令 clear all&#xff1a;清除所有工作区的内容 注释&#xff1a;两个% 空格 %% matlab的数据类型 1、数字 3 3 * 5 3 / 5 3 5 3 - 52、字符与字符串 s a %% 求s的ascill码 abs(s) char(97) num2str(65) str I…

curl: (56) Recv failure : Connection reset by peer

文章目录 背景原因可能如下1. 服务器端关闭了连接2. 网络问题3. 防火墙或代理问题4. 服务器负载过高 解决办法 背景 docker容器里有http服务&#xff0c;今天在docker容器重启时&#xff0c;去调用http接口&#xff0c;出现了以下错误&#xff1a; curl: (56) Recv failure :…

记一次ruoyi中使用Quartz实现定时任务

一、首先了解一下Quartz Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目&#xff0c;它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个&#xff0c;百个&#xff0c;甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标…

Deepin/UOS Linux 桌面自定义 IDEA/DataGrip 应用程序图标

在 $HOME/Desktop目录下编辑 vim jetbrains.intelij.idea.desktop [Desktop Entry] TypeApplication NameIntelij IDEA Icon/opt/module/idea-IU-203.8084.24/bin/idea.png Exec/opt/module/idea-IU-203.8084.24/bin/idea.sh Terminalfalse CategoriesDevelopment;IDE;vim je…

自动化运维工具——Ansible学习(二)

目录 一、handlers和notify结合使用触发条件 1.新建httpd.yml文件 2.复制配置文件到ansible的files目录中 3.卸载被控机已安装的httpd 4.执行httpd.yml脚本 5.更改httpd.conf配置文件 6.使用handlers 7.重新执行httpd.yml脚本 8.检查被控机的端口号是否改变 9.handle…

Block

文章目录 前言Block本质Block循环引用解决循环引用1.__weak __strong协作2.__block3.参数传递 Block中对象的引用计数Block Copy__blockBlock的分类 前言 之前学过Block了&#xff0c;那就在学学 之前学习Block的博客 参考 提示&#xff1a;以下是本篇文章正文内容&#xff…

AtcoderABC249场

A - JoggingA - Jogging 题目大意 高桥和青木一起慢跑&#xff0c;高桥每隔 ACAC 秒钟走 BB 米&#xff0c;然后休息 CC 秒钟&#xff0c;青木每隔 DFDF 秒钟走 EE 米&#xff0c;然后休息 FF 秒钟。现在已经过去了 XX 秒钟&#xff0c;问谁跑得更远。 思路分析 模拟来解决这…

【广州华锐互动】智慧交通3D可视化交互平台

智慧交通3D可视化交互平台由广州华锐互动开发&#xff0c;是一种基于现代科技的智能交通管理系统&#xff0c;它能够实现对车站内部人员和车辆的实时监控和管理。该平台采用了先进的三维可视化技术&#xff0c;将车站内部的结构和设备以立体、直观的方式呈现在用户面前&#xf…

【云原生】Docker网络Overlay搭建Consul实现跨主机通信

目录 1.overlay网络是什么&#xff1f; 实现overlay环境 1.overlay网络是什么&#xff1f; 在Docker中&#xff0c;Overlay网络是一种容器网络驱动程序&#xff0c;它允许在多个Docker主机上创建一个虚拟网络&#xff0c;使得容器可以通过这个网络相互通信。 Overlay网络使用…

echarts 横向柱状图 刻度标签

echarts 横向柱状图 刻度标签 怎么调试都不左对齐 将width去掉固定宽度 echarts会自适应

tql!一款Go编写的RAT主机管理工具

工具介绍 这是一款使用go编写的RAT主机群管理工具&#xff0c;已具备命令控制台、文件管理、屏幕截屏、开机启动服务、NPS代理等功能。 流量&#xff1a;支持TCP&#xff0c;UDP/KCP协议&#xff0c;通讯默认使用tls证明书进行加密 关注【Hack分享吧】公众号&#xff0c;回复…

数据结构初阶--排序2

目录 前言快速排序思路hoare版本代码实现挖坑法代码实现前后指针法代码实现 快排优化三项取中法代码实现三指针代码实现 快排非递归代码实现 归并排序思路代码实现归并非递归代码实现 计数排序思路代码实现 前言 本篇文章将继续介绍快排&#xff0c;归并等排序算法以及其变式。…

Docker本地镜像发布到阿里云

我们构建了自己的镜像后&#xff0c;可以发布到远程镜像提供给其他人使用&#xff0c;比如发布到阿里云 使用build/commit生成新的镜像&#xff0c;并生成自己镜像的版本标签tag&#xff0c;此新的镜像在自己的本地库中&#xff0c;使用push可以将镜像提交到阿里云公有库/私有库…

FPGA——pwm呼吸灯

文章目录 一、实验环境二、实验任务三、实验过程3.1 verilog代码3.2 引脚配置 四、仿真4.1 仿真代码4.2 仿真结果 五、实验结果六、总结 一、实验环境 quartus 18.1 modelsim vscode Cyclone IV开发板 二、实验任务 呼吸灯是指灯光在微电脑的控制之下完成由亮到暗的逐渐变化…

数据结构顺序表,实现增删改查

一、顺序表结构体定义 #define MAXSIZE 8 //定义常量MAXSIZE&#xff0c;表示数据元素的最大个数为8 typedef int datatype; //重定义int类型&#xff0c;分别后期修改顺序表中存储的数据类型 typedef struct {int len; //顺序表长度datatype data[MAXSIZE…

考研线性代数考点总结

一.行列式 1.数字型行列式 数字行列式的计算含零子式的分块计算 2.行列式的性质 |A||A^T|交换行列&#xff0c;行列式的值变号含公因子的提出或乘进去把某行的K倍加到另一行&#xff0c;行列式的值不变。行列式可以根据某一行或某一列分拆 3.抽象行列式 n阶或高阶行列式 常…
最新文章