MyBatis——增删改查操作的实现
开启mybatis sql日志打印
可以在日志中看到sql中执行的语句
在配置文件中加上下面这几条语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
logging.level.com.example.demo=debug
查询操作
根据用户id查询用户
UserMapper:
UserInfo getUserById(@Param("user_id") Integer id);
UserMapper.xml:
<select id="getUserById" resultType="com.example.demo.entity.UserInfo">select * from userinfo where id=${user_id}
</select>
我们可以使用单元测试来测试查询到的信息是否正确
单元测试有如下特点:
- 快速生成一个方法,来测试一个功能模块
- 只有所有单元测试通过才会打包,防止程序出现bug
- 用单元测试的事务可以回滚到未测试状态,不会污染数据库的数据
可以看到,spring中自带单元测试的依赖,我们不用再引用junit了

只需要在要测试的类中右键,选择generate,test,即可创建单元测试


勾选需要添加的单元测试方法

然后就会在test包下生成对应的测试类
添加@SpringBootTest注解可以让当前测试类运行在springBoot环境中
添加@Transactional注解,可以创建事务,运行完测试类后会回滚到初始状态,不会污染数据
@SpringBootTest
@Transactional
class UserMapperTest {@AutowiredUserMapper userMapper;@Testvoid getUserById(){UserInfo userInfo = userMapper.getUserById(1);System.out.println(userInfo); Assertions.assertEquals("admin",userInfo.getUsername());}
}
可以看到,查询到对应的userinfo对象,并且控制台中有详细的sql语句

也可以使用#通配符
<select id="getUserById" resultType="com.example.demo.entity.UserInfo">select * from userinfo where id=#{user_id}
</select>

可以发现,使用$是直接用1替换id,而使用#则是先使用占位符?,再在后面的语句中用1替换
查询所有用户
UserMapper:
List<UserInfo> getAll();
UserMapper.xml:
<select id="getAll" resultType="com.example.demo.entity.UserInfo">select * from userinfo
</select>
UserMapperTest:
@Test
void getAll() {List<UserInfo> list = userMapper.getAll();Assertions.assertEquals(1, list.size());
}

根据用户名查询用户
UserMapper:
List<UserInfo> getUserByName(String username);
UserMapper.xml:
<select id="getUserByName" resultType="com.example.demo.entity.UserInfo">select * from userinfo where username=#{username}
</select>
UserMapperTest:
@Test
void getUserByName() {List<UserInfo> list = userMapper.getUserByName("admin");System.out.println(list.size());
}
这时查找是成功的:

如果使用$,则会不成功
<select id="getUserByName" resultType="com.example.demo.entity.UserInfo">select * from userinfo where username=${username}
</select>

可以看到,sql语句中直接将username替换成admin,而没有加上"",因此导致了查询操作不成功
#和$的区别
同样是占位符,#是预编译处理,也就是先将sql中的#{}内容替换成?然后在使用PreparedStatement的set方法来赋值操作
因此在替换时,admin会自动加上""
而$则是直接替换操作,因此admin没有加上""
而直接替换也有好处,例如我们要按顺序查找数据时,就不需要""了,因此需要使用$
<select id="getAllBySort" resultType="com.example.demo.entity.UserInfo">select * from userinfo order by id ${sort}
</select>

增添操作
UserMapper:
Integer add(UserInfo userInfo);
UserMapper.xml:
除了查找操作,其他的几种操作都不需要指定返回类型了,并且可以直接使用对象中的属性来进行插入操作
<insert id="add">insert into userinfo(username,password,createtime,updatetime)values(#{username},#{password},#{createTime},#{updateTime})
</insert>
UserMapperTest:
@Test
void add() {UserInfo userInfo = new UserInfo();userInfo.setUsername("san");userInfo.setPassword("123");userInfo.setCreateTime(LocalDateTime.now());userInfo.setUpdateTime(LocalDateTime.now());int result = userMapper.add(userInfo);System.out.println(result);Assertions.assertEquals(1, result);
}

添加自增id
在xml中将useGeneratedKeys设置为true,表示mybatis中使用数据库内部生成的主键
而keyProperty的值,可以指定唯一识别对象的属性,也就是说mybatis会使用getGeneratedKeys的返回值来设置值
<insert id="addGetId" useGeneratedKeys="true" keyProperty="id">insert into userinfo(username,password,createtime,updatetime)values(#{username},#{password},#{createTime},#{updateTime})
</insert>
修改操作
UserMapper:
int upUserName(UserInfo userInfo);
UserMapper.xml:
<update id="upUserName">update userinfo set username=#{username} where id=#{id}
</update>
UserMapperTest:
@Test
void upUserName() {UserInfo userInfo = new UserInfo();userInfo.setId(2);userInfo.setUsername("si");int result = userMapper.upUserName(userInfo);System.out.println(result);Assertions.assertEquals(1,result);
}

删除操作
UserMapper:
int delById(@Param("id") Integer id);
UserMapper.xml:
<delete id="delById">delete from userinfo where id=#{id}
</delete>
UserMapperTest
@Test
void delById() {Integer id = 2;int result = userMapper.delById(id);System.out.println(result);Assertions.assertEquals(1,result);
}

相关文章:
MyBatis——增删改查操作的实现
开启mybatis sql日志打印 可以在日志中看到sql中执行的语句 在配置文件中加上下面这几条语句 mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl logging.level.com.example.demodebug查询操作 根据用户id查询用户 UserMapper: User…...
【7】linux命令每日分享——cat查看文件内容
大家好,这里是sdust-vrlab,Linux是一种免费使用和自由传播的类UNIX操作系统,Linux的基本思想有两点:一切都是文件;每个文件都有确定的用途;linux涉及到IT行业的方方面面,在我们日常的学习中&…...
新氧2023年财务业绩预测:退市风险大幅降低,收入增长将放缓
来源:猛兽财经 作者:猛兽财经 公司进展 与新氧(SY)有关的两个重要积极进展值得一提。 第一个积极进展是新氧的退市风险已在很大程度上降低。 2023年1月6日,新氧披露,它已经“重新符合纳斯达克规定的股价每…...
C++使用shared_ptr与weak_ptr轻松管理内存
智能指针之shared_ptr与weak_ptr前言智能指针实例分析前言 C与其他语言的不同点之一就是可以直接操作内存,这是一把双刃剑,直接操作内存可以提高开发的灵活度,开发人员在合适的时机申请内存,在合适的时机释放内存,减少…...
Buuctf reverse [FlareOn4]IgniteMe 题解
一. 查壳 无壳32位程序 二. ida打开 GetStdHandle函数根据微软官方文档可以得知是获取标准输入/输出/错误的句柄 参数里的 0xFFFFFFF6转换一下是4294967286, 对应(DWORD) -10 所以这里的WriteFile函数实际上是实现了printf的功能 sub_4010F0()函数 其功能是通过ReadFile函数读取…...
ChatGPT懂SAP吗?跟ChatGPT聊完后,我暂时不担心会失业
我弄了个ChatGPT账号。随便问了一下他SAP的问题。贴出来跟大家分享一下。 问题1:我是 SAP 开发工程师,你有什么可以帮到我。 作为一个语言模型,我可以为您提供关于SAP开发的一般性建议,以及关于如何使用SAP软件的一些技巧。以下是…...
Communications link failure 解决方法 !!!
Communications link failure 解决方法 最近在使用mybatis逆向生成的时候遇到了link failure的问题, 这里记录解决方法 文章目录Communications link failure 解决方法generatorConfig 里的数据库链接或数据库或密码或账户填写错误mysql响应时间设置太短, 还没等链接上就关闭连…...
pytorch入门2--数据预处理、线性代数的矩阵实现、求导
数据预处理是指将原始数据读取进来使得能用机器学习的方法进行处理。 首先介绍csv文件: CSV 代表逗号分隔值(comma-separated values),CSV 文件就是使用逗号分隔数据的文本文件。 一个 CSV 文件包含一行或多行数据,每一…...
15.消息队列RabbitMQ
一、基本概念 RabbitMQ 是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息…...
并发编程之死锁问题介绍
一、本文概览 死锁问题在并发编程中是一个非常致命的问题,问题一旦产生,只能通过重启机器、修改代码来修复问题,下面我们通过一小段文章内容介绍下死锁以及如何死锁的预防 二、什么是死锁? 在介绍死锁之前,先来明确下什…...
【python学习笔记】:SQL常用脚本(一)
1、行转列的用法PIVOT CREATE table test (id int,name nvarchar(20),quarter int,number int) insert into test values(1,N苹果,1,1000) insert into test values(1,N苹果,2,2000) insert into test values(1,N苹果,3,4000) insert into test values(1,N苹果,4,5000) insert…...
Spring是怎么解决循环依赖的
1.什么是循环依赖: 这里给大家举个简单的例子,相信看了上一篇文章大家都知道了解了spring的生命周期创建流程。那么在Spring在生命周期的哪一步会出现循环依赖呢? 第一阶段:实例化阶段 Instantiation 第二阶段:属性赋…...
HTML创意动画代码
目录1、动态气泡背景2、创意文字3、旋转立方体1、动态气泡背景 <!DOCTYPE html> <html> <head><title>Bubble Background</title><style>body {margin: 0;padding: 0;height: 100vh;background: #222;display: flex;flex-direction: colum…...
软工第一次个人作业——阅读和提问
软工第一次个人作业——阅读和提问 项目内容这个作业属于哪个课程2023北航敏捷软件工程这个作业的要求在哪里个人作业-阅读和提问我在这个课程的目标是体验敏捷开发过程,掌握一些开发技能,为进一步发展作铺垫这个作业在哪个具体方面帮助我实现目标对本课…...
urho3d的自定义文件格式
Urho3D尽可能使用现有文件格式,仅在绝对必要时才定义自定义文件格式。当前使用的自定义文件格式有: 二进制模型格式(.mdl) Model geometry and vertex morph data byte[4] Identifier "UMDL" or "UMD2" …...
spark第一章:环境安装
系列文章目录 spark第一章:环境安装 文章目录系列文章目录前言一、文件准备1.文件上传2.文件解压3.修改配置4.启动环境二、历史服务器1.修改配置2.启动历史服务器总结前言 spark在大数据环境的重要程度就不必细说了,直接开始吧。 一、文件准备 1.文件…...
MySQL---存储过程与存储函数的相关概念
MySQL—存储过程与存储函数的相关概念 存储函数和存储过程的主要区别: 存储函数一定会有返回值的存储过程不一定有返回值 存储过程和函数能后将复杂的SQL逻辑封装在一起,应用程序无需关注存储过程和函数内部复杂的SQL逻辑,而只需要简单地调…...
PMP值得考吗?
第一,PMP的价值体现 1、PMP是管理岗位必考证书。 多数企业会选择优先录用持PMP证书的管理人才,PMP成为管理岗位的必考证书。PMP在很多外企和国内中大型企业非常受重视,中石油、中海油、华为等等都会给内部员工做培训。 这些机构对项目管理…...
Quartus 报错汇总(持续更新...)
1、Error (10663): Verilog HDL Port Connection error at top_rom.v(70): output or inout port "stcp" must be connected to a structural net expression输出变量stcp在原设计文件中已经定义为reg型,在实例化时不能再定义为reg型,而应该是…...
Netty权威指南总结(一)
一、为什么选择Netty:API使用简单,开发门槛低,屏蔽了NIO通信的底层细节。功能强大,预制了很多种编解码功能,支持主流协议。定制能力强,可以通过ChannelHandler对通信框架进行灵活地拓展。性能高、成熟、稳定…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
