Mybatis 实现简单增删改查

目录

前言

一、Mybatis是什么

二、配置Mybatis环境

 三、创建数据库和表

 四、添加业务代码

4.1、添加实体类

4.2、添加mapper接口 

4.3、添加实现接口方法的xml文件

五、简单的增删改查操作及单元测试

5.1、单元测试

 单元测试具体步骤:

单元测试如何才能不污染数据库

5.2、查询操作

不带参数的查询

带参数查询

5.3、 修改操作

接口方法传递对象的操作

5.4、删除操作

5.5、添加操作

添加之后返回受影响行数

添加操作之后返回自增id

5.6、like查询

5.7、#{}和${}的区别

六、使用注解来实现增删改查功能

6.1、@Select注解

6.2、@Insert注解

6.3、@Update注解

6.4、@Delete注解

使用注解的与使用xml方式书写SQL语句的对比

前言

        本篇博客主要介绍如何在spring boot项目中配置Mybatis、Mybatis如何连接MySQL数据库、使用Mybatis通过配置文件和注解的实现简单的单表的增删改查操作,还有使用单元测试进行数据库的操作测试。

一、Mybatis是什么

        MyBatis 是⼀款优秀的持久层框架,它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO(Plain Old Java Objects,普通⽼式 Java 对象)为数据库中的 记录。 简单来说 MyBatis 是更简单完成程序和数据库交互的⼯具,也就是更简单的操作和读取数据库⼯具。

二、配置Mybatis环境

        要配置Mybatis环境主要需要两大步骤,首先需要引入Mybaits的框架依赖还有MySQL数据库的驱动依赖,操作如下所示:只需要在创建项目的时候点击添加相关依赖即可

如果在创建时忘记添加可以在创建后在pom.xml中添加。

        第二步就是在项目创建好之后在配置文件中设置数据库的连接信息,这一步非常重要,如果没有配置的话,运行项目就会报错。(这里配置以MySQL为例)

配置操作如下:在application.properties中配置

        以下内容需要修改的就是url中连接的数据库名称,以及数据库密码,还有xml保存路径信息,其他的一般可以不修改。

# 配置数据库的连接字符串
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
spring.datasource.username=root
#设置自己数据库密码
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 设置 Mybatis 的 xml 保存路径,以下代表的意思是说明配置文件位于mapper包下以Mapper结尾的xml文件
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 执行的 SQL属于debug级别的日志,所以需要设置成debug,项目上线后一般就不要去打印了
logging.level.com.example.blogmybatis=debug

 三、创建数据库和表

        我们要想操作数据库,那么要操作的数据库是必须有的以及数据库中的表也必须要有。这里我们创建一个userinfo表作为例子演示增删改查操作:代码如下

create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default '',createtime timestamp default now(),updatetime timestamp default now(),`state` int default 1
) default charset 'utf8mb4';
insert into userinfo(username,password) values('zhangsan','123');

 四、添加业务代码

4.1、添加实体类

在项目中添加与数据库表相对应的实体类:

        创建这个实体类主要是为了可以在项目中使用这个类来接收我们查询返回的信息,只要数据库中的字段名与实体类中属性名一致,框架就会自动的帮我们进行赋值。

package com.example.blogmybatis.model;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class UserInfo {//以下字段名要与数据库中字段名一致private int id;private String username;private String password;private String photo;private LocalDateTime createtime;private LocalDateTime updatetime;private int state;
}

4.2、添加mapper接口 

我们添加mapper接口的目的就是在接口中声明方法,而方法的具体实现是在xml配置文件中的。

代码如下:

package com.example.blogmybatis.model.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper//Mapper注解不能省
public interface UserMapper {//在以下类中定义方法}

4.3、添加实现接口方法的xml文件

这个文件的位置是需要与我们前面的配置文件中设置的路径一致的,需要在mapper目录下,而且以Mapper结尾。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.blogmybatis.mapper.UserMapper"></mapper>

        配置这个需要注意的是,接口的名字和实现接口的xml方法二者之间的名字不一定需要相同,因为二者之间的关联并不是通过这个名字关联的,二者之间是通过namespace属性关联的,所以一旦namespace属性写错了,就会无法正确的实现接口中的方法,执行就会报错。

五、简单的增删改查操作及单元测试

      我们这里的增删改查操作都需要现在接口中去声明方法,指定方法返回类型,接着去对应的xml文件中实现接口中声明的方法。

xml中实现方法的具体步骤:

        根据要进行的操作,进行选择标签,查询标签就是select,修改标签就是update,删除标签就是delete,增加标签就是insert。接着设置id,id就是接口中的方法名,最后再设置返回类型resultType,这个设置的是返回的基本类型,比如:返回的是List<User>,那么需要设置的就是User类型,而不是List类型

5.1、单元测试

这里介绍单元测试主要是为了后续可以快捷的测试我们写的代码是否可以正确的操作数据库。

单元测试的概念:

        单元测试(unit testing),是指对软件中的最⼩可测试单元进⾏检查和验证的过程就叫单元测试。 单元测试是开发者编写的⼀⼩段代码,⽤于检验被测代码的⼀个很⼩的、很明确的(代码)功能是否正 确。执⾏单元测试就是为了证明某段代码的执⾏结果是否符合我们的预期。如果测试结果符合我们的预 期,称之为测试通过,否则就是测试未通过(或者叫测试失败)。

单元测试的好处:

1、可以⾮常简单、直观、快速的测试某⼀个功能是否正确。

2、使⽤单元测试可以帮我们在打包的时候,发现⼀些问题,因为在打包之前,所以的单元测试必须通过,否则不能打包成功。

3、使⽤单元测试,在测试功能的时候,可以不污染连接的数据库,也就是可以不对数据库进⾏任何改变的情况下,测试功能

Spring Boot中单元测试的使用: 

        我们要使用单元测试,那首先得有一个单元测试的框架,而我们在创建Spring Boot项目时,Spring已经帮我们内置了一个单元测试的框架了(内置了spring-boot-test),所以这里并不需要我们自己去引入依赖,这个内置的单元测试框架是基于Junit实现的,在pom.xml中就可以看到:如下

 单元测试具体步骤:

1.生成单元测试类:

2.编写单元测试代码

单元测试的类是必须加上SpringBootTest注解的,不然是无法正确执行的。

执行之后结果:这个也就是上面查询全部用户信息的结果

当我们在同一个类中再次使用相同的方法生成单元测试时,会出现报Error的情况:直接点击ok即可

单元测试如何才能不污染数据库

        我们前面的单元测试,都是直接去操作数据库,修改数据库中的内容,但是我们有时候是并不希望数据库的内容直接被修改的,而只是想要知道执行的结果是否正确。因此Spring Boot中是有提供一个@Transactional注解的,这个注解的作用就是开启一个事务,这个事务在我们测试方法返回前,会执行回滚操作,这个操作就是将我们修改过的数据库内容进行回滚,这样子我们在单元测试时,就不会真的去修改数据库了。

代码演示:(以下为插入数据的操作)

执行结果:从控制台打印的日志信息我们可以直观的看出我们的事务在执行回滚操作了 

5.2、查询操作

不带参数的查询

我们在xml文件中写sql语句是不需要带分号的,我们这里的需求是查询数据库中所有用户的信息

以上就是我们一个最简单的查询数据库中所有用户信息的操作。单元测试的结果如下所示:

带参数查询

sql语句中如何接收动态参数:

        从上面的sql语句中,我们可以看出,我们可以使用#{}和${}的方式来接收参数的,其中我们只要将参数的名称填入{}中就可以,这里使用#{}和${}之一都可以,至于这两者的区别后面再介绍。

        还有带参数查询在接口的方法中我们使用到了@Param注解,这个注解一般都要加上,不加的话有小部分人的程序会报错,这个注解的作用是用来命名的,注解中的名字要求要与我们实现的接口方法中的sql语句中{}中参数名字一致才可以。

执行单元测试的代码及结果:

5.3、 修改操作

现在我们的需求是要将数据库中id为1的用户名改为admin,这时候我们的操作如下:

单元测试的代码及结果:

接口方法传递对象的操作

        在上面的update操作中, 我们一共是传递了两个参数,这其实并不是很多,但是,有时候我们是需要传递多个参数进行修改或者查询操作的,但是,这时候我们如果一个参数一个参数的去传,那么我们的形参列表就会变得很长,代码并不美观,可读性可维护性都不强,所以这个时候我们就可以考虑 直接传递一个对象过去,这样子代码就更加的美观了,也更好维护了。

        那对象传递过去之后在xml中到底该如何拿到对象中的属性,如何去使用呢?我们直接将上一步的的修改操作的传递参数操作改为传递对象,接下来直接看代码:

单元测试代码及结果: 这里单元测试只需要看返回受影响行数就可以,因为修改成功的话,受影响行数就会是1,修改失败的话受影响行数就会是0

        通过代码我们可以得知:传递对象其实和传递参数的区别就在于接口方法中的形参列表的不同,在我们xml中的使用是完全不变的,我们只需要保证xml中#{}中的参数名字与对象中的属性名可以对应上就可以。 

5.4、删除操作

        删除操作与前面的操作也是类似的,只要使用delete标签就可以了。现在假设我们要把数据库中id为2的用户删了,相应的代码如下:

单元测试代码及结果:

5.5、添加操作

        普通的添加操作和之前的操作也是差不多的,普通的添加操作就是在添加之后会返回受影响的行数。但是添加操作中还有一个比较特别的就是,我们有时候需要在添加完之后去返回我们的自增id这个字段,返回自增id这个操作就比较麻烦了,接下去我们直接使用代码来演示这两个操作。

添加之后返回受影响行数

代码如下:

单元测试结果:

添加操作之后返回自增id

代码如下:

单元测试的代码及结果如下:

        这里需要注意的就是,我们需要将数据库中的自增主键赋值给某一个属性,所以这里我们一般是使用对象来传参之后才能将自增主键返回到对象的属性中,不使用对象的话就无法获取这里的自增id了。当然,也可以使用Map来传参,这里就不再演示,因为使用对象传参还是比较主流的写法的。

5.6、like查询

        like查询在实际的开发中,还是经常会使用到的,like查询就是给定关键字,然后我们可以去数据库中根据关键字进行查询。假设我们现在要查询名字中含有‘wang’这个关键字的,那么我们的sql就如下所示:

单元测试代码及结果:

        关于like查询需要注意的是:我们这里传过来的参数,一般得使用#{}来接收,这里如果使用${}来接收可能就会直接报错,这是因为${}会被认为是常量,而不是变量。换句话说,MyBatis会尝试直接在SQL查询中使用${}中的值,而不是将其视为一个变量来处理。而且使用${}还有可能会有sql注入的风险,因此like查询建议都使用#{}就不会出现问题

5.7、#{}和${}的区别

        这是一个我们在面试中经常会遇到的一个问题,我们这里先给出二者之间的区别,接着再使用代码来进行解释;

#{}和${}的区别:

1.#{}是安全的,不存在SQL注入的问题,${}是不安全的,存在SQL注入的问题;

2.#{}是预编译处理,而${}是直接替换;

        什么是SQL注入:SQL注入的场景有很多,但是简单来说,就是利用SQL语句的漏洞来查询到原本不应该查询到的数据,进而达成某种目的。

SQL注入的代码案例:

        从上面的代码我们就可以看出:我们输入的是一个完全错误的密码,但是却可以从数据库中查到正确的数据,所以这就很不安全,可能会被攻击,这就是因为使用${}直接替换的结果。

对于上面的SQL语句的分析:

#{}预编译和${}直接替换的区别: 

        从图中我们可以看出,使用${}就是直接将参数给替换进去就执行sql,而使用#{}是将sql中的参数先用?这个占位符进行替换,最后再使用set方法来为占位符进行赋值,预编译处理会将参数值作为参数传递给数据库,而不是直接将参数值拼接到SQL语句中,传递给数据库之后数据库就不是使用直接拼接的方式来完成了,数据库是根据参数的值来进行查找的。这样可以防止恶意用户通过参数值注入恶意的SQL代码。

六、使用注解来实现增删改查功能

6.1、@Select注解

代码演示:

单元测试代码及结果:

6.2、@Insert注解

代码演示:

单元测试代码及结果:

6.3、@Update注解

代码演示:

单元测试代码及结果:

6.4、@Delete注解

代码演示:

单元测试及结果:

使用注解的与使用xml方式书写SQL语句的对比

使用注解的优缺点:

优点:

简洁:使用注解可以直接在Java代码中编写SQL语句,不需要额外的XML文件,减少了配置的复杂性。

易于维护:注解方式将SQL语句与Java代码紧密结合,易于理解和维护。所有的SQL语句都在Java代码中,方便查找和修改。

更好的集成性:注解方式适合于简单的SQL语句和快速开发,特别是对于一些简单的CRUD操作,可以减少XML配置的工作量。

缺点:

可读性差:注解方式将SQL语句直接写在Java代码中,可能会导致代码可读性较差,特别是对于复杂的SQL语句。

不利于动态SQL和复杂SQL:注解方式不太适合编写动态SQL,因为注解是静态的,不容易根据条件动态生成SQL语句。

缺乏分离性:注解方式将SQL语句与Java代码紧密结合,缺乏了SQL和Java代码的分离,不利于维护和修改。

使用XML的优缺点:

优点:

可读性好:XML方式将SQL语句和映射配置分离,使得代码更加清晰可读,特别是对于复杂的SQL语句和映射关系。

动态SQL支持:XML方式支持动态SQL,可以根据条件动态生成SQL语句,提供了更大的灵活性。

易于维护:XML方式将SQL语句和映射配置集中在一个地方,便于维护和修改。

缺点:

繁琐:XML方式需要编写额外的XML文件来配置SQL语句和映射关系,相对于注解方式来说,配置的工作量较大。

学习成本高:XML方式需要了解和掌握MyBatis的XML配置规则,对于新手来说,学习成本可能较高。

不够直观:相对于注解方式,XML方式的配置不够直观,需要在XML文件中编写SQL语句和映射关系。

总的来说,一般是会使用xml的方式,因为xml的方式能够写动态SQL和复杂的SQL,但是如果项目比较简单也可以使用注解的方式。

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

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

相关文章

好莱坞编剧大罢工终于结束;与OpenAI创始人共进早餐;使用DALL-E 3制作绘本分享;生成式AI的基础设施架构 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 好莱坞编剧大罢工终于结束&#xff1a;简单说就是AI妥协了 https://www.wgacontract2023.org/the-campaign/summary-of-the-2023-wga-…

【Python爬虫 js渲染思路一】

Python爬虫 破解js渲染思路一 当我们在谈论网页js渲染的时候&#xff0c;我们在谈论什么 js渲染网页&#xff0c;从某种程度来说&#xff0c;是指单纯的http请求&#xff0c;返回的文本数据&#xff0c;与我们在浏览器看到的内容&#xff0c;相距甚远.其可包括为以下几点&…

C++的高手之旅

要学习C并成为C大佬&#xff0c;以下是一些建议&#xff1a; 掌握C基础知识&#xff1a;C是一种面向对象的编程语言&#xff0c;它包含了C语言的大部分语法和特性。因此&#xff0c;学习C之前&#xff0c;建议先掌握C语言的基础知识&#xff0c;包括数据类型、控制流、指针、内…

微调Yolov8动物姿势估计模型

本文主要以狗的姿势估计为例,展示如何对当下流行的YOLOv8姿势模型进行Fine-tuning,并附录完整代码。 动物姿势估计是计算机视觉领域的一个研究方向,它是人工智能的一个子领域,专注于自动检测和分析图像或视频中动物的姿势和位置。其目标是确定一个或多个动物身体部位的空间…

msvcr120.dll丢失怎样修复?总结msvcr120.dll丢失的5修复方法

在使用计算机的过程中&#xff0c;我们常常会遇到各种问题&#xff0c;其中之一就是“计算机丢失msvcr120.dll丢失的困扰”。这个问题可能对一些人来说并不陌生&#xff0c;但是对于初次遇到这个问题的人来说&#xff0c;可能会感到无所适从。因此&#xff0c;小编将详细探讨这…

免费开源的非标项目型制造BOM一键导入方案介绍

非标项目型制造&#xff0c;每一个订单都会引入很多新料号、新BoM、新工艺路线。实施ERP/MES系统&#xff0c;实现生产管理数字化&#xff0c;第一步就是要导入这些料号、BoM和工艺。项目型制造&#xff0c;大多数订单只生产一次。但在ERP/MES系统中&#xff0c;订单的料号、Bo…

【Unity】【VR】如何让Distance Grab抓取物品时限制物品的Rotation

【背景】 遇到这样的场景,希望抓取Canvas时,Canvas不会沿Z轴旋转。 【问题】 发现Freeze Canvas的Rigid Body没有用。 【分析】 应该是RigidBody的限制仅在物理互动下生效,抓取可能不属于物理互动(比如碰撞),所以不生效。 【思路】 还是得写脚本挂载在Interacta…

存档&改造【06】Apex-Fancy-Tree-Select花式树的使用误删页数据还原(根据时间节点导出导入)

之前一直想实现厂区-区域-产线之间的级联选取&#xff0c;于是导入插件Apex-Fancy-Tree-Select花式树 存档&#xff06;改造【03】Apex-Fancy-Tree-Select花式树的导入-CSDN博客 现在则是在Oracle Apex中的应用 花式书级联列表展示厂区-区域-产线 想要实现的效果 由厂区>…

Day 6 C++

#include <iostream> //不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&#xff0c;他会为每种动物表演做简单的介 //绍。定义一个基类 Animal&#xff0c;其中有一个虛函数perform&#xff08;)&#xff0c;用于在子类中实现不…

真人现在猫鼠躲猫猫游戏搭建流程:专业思考与深度思考

真人现在猫鼠躲猫猫游戏是种充满乐趣和挑战的团队竞技游戏。本文将从游戏规则设计、场地布置、技术实现和用户体验等方面&#xff0c;深入探讨人现在猫鼠躲猫猫游戏的搭建流程&#xff0c;并结合专业思考与深度思考&#xff0c;为游戏搭建提供全面指导。 一、游戏规则设计&…

网工笔记整理:策略工具Filter-policy的使用

一、概述 Filter-Policy&#xff08;过滤-策略&#xff09;是一个很常用的路由信息过滤工具&#xff0c;能够对接收、发布、引入的路由进行过滤&#xff0c;可应用于IS-IS、OSPF、BGP等协议。 Filter-policy在距离矢量路由协议中的应用 filter-policy import&#xff1a;不发…

行业追踪,2023-10-11

自动复盘 2023-10-11 凡所有相&#xff0c;皆是虚妄。若见诸相非相&#xff0c;即见如来。 k 线图是最好的老师&#xff0c;每天持续发布板块的rps排名&#xff0c;追踪板块&#xff0c;板块来开仓&#xff0c;板块去清仓&#xff0c;丢弃自以为是的想法&#xff0c;板块去留让…

Linux进程概念(二)--进程状态进程优先级

继上回书Linux进程概念&#xff08;一&#xff09;&#xff0c;我们初步了解了进程的一些相关概念以及如何创建和查看进程&#xff0c;对其原理和一些进程现象进行了分析和解释&#xff0c;那么今天&#xff0c;我们学习下一个进程知识-进程概念。 目录 1.操作系统的进程状态 …

Java List 中存不同的数据类型

在最近的实践中&#xff0c;有人突然问了一个问题&#xff1a; 在 Java 的 List 中可以存不同的数据类型吗&#xff1f; 这个问题突然给问到了&#xff0c;我们都知道 Java 中的 List 中存的是对象&#xff0c;通常我们定义都会这样的定义&#xff1a; List<String> t…

SRC实战-cookie注入漏洞

目录 谷歌语法-信息收集 cookie注入 实战演示 信息收集 SQL注入判断 查找字段数 爆破表名 输出结果 总结 本文由掌控安全学院 - 小博 投稿 谷歌语法-信息收集 1.查找带有ID传参的网站&#xff08;可以查找sql注入漏洞&#xff09; inurl:asp idxx 2.查找网站后台&…

AlGaN/GaN结构的氧基数字蚀刻

引言 宽带隙GaN基高电子迁移率晶体管(HEMTs)和场效应晶体管(fet)能够提供比传统Si基高功率器件更高的击穿电压和电子迁移率。常关GaN非常需要HEMT来降低功率并简化电路和系统架构&#xff0c;这是GaN HEMT技术的主要挑战之一。凹进的AlGaN/GaN结构是实现常关操作的有用选择之一…

华为云云耀云服务器L实例评测|华为云耀云服务器L实例评测包管理工具安装软件(六)

七、华为云耀云服务器L实例评测包管理工具安装软件&#xff1a; 根据企业级项目架构图所示&#xff0c;本章主要是安装公司企业项目的基本环境LNMP&#xff0c;相关的包管理器Composer、Node、Npm、Yarn安装&#xff0c;评测一下包管理工具安装软件是否存在问题&#xff0c;如果…

区块链技术在供应链管理中的创新应用

区块链技术以其独特的不可篡改和透明性特点&#xff0c;正在逐步改变供应链管理的传统模式。本文将探讨区块链技术在供应链管理中的创新应用及其带来的效益。 区块链技术的出现为许多行业带来了创新的可能&#xff0c;其中之一就是供应链管理。通过区块链技术&#xff0c;企业可…

RS485电路设计

引言 今天学习RS485电路的设计。 首先先来了解一下RS485电路是什么干什么。 RS485是一种串行通信协议&#xff0c;也是一种电气标准。它可以用于在远距离范围内传送数据&#xff0c;最长传输距离可以达到1200米&#xff0c;可以支持多个设备同时通信。RS485通常应用于工业自…

空间精密定位与导航VR模拟培训软件突破了时空限制

随着科技的飞速发展&#xff0c;测绘遥感技术逐渐成为地理信息获取的重要手段。然而&#xff0c;传统的测绘展示方式存在着诸多局限性&#xff0c;无法充分展现出测绘数据的精细化和多元化&#xff0c;成为为解决这一难题的有效途径。 测绘工程专业作为时下就业率爆棚的专业之一…