【MyBatis】操作数据库——入门

在这里插入图片描述

文章目录

  • 为什么要学习MyBatis
  • 什么是MyBatis
  • MyBatis 入门
    • 创建带有MyBatis框架的SpringBoot项目
    • 数据准备
    • 在配置文件中配置数据库相关信息
    • 实现持久层代码
    • 单元测试

为什么要学习MyBatis

前面我们肯定多多少少学过 sql 语言,sql 语言是一种操作数据库的一类语言,数据库是保证数据能够持久化存储的一种集合。在众多 sql 语言中,MySQL就是其中一种,并且是人们使用较多的一种 sql 语言,而就是因为 MySQL 使用较简单,使用的人较多,所以就出现了 JDBC 编程,也就是 Java 的一个 API,可以让我们通过 Java 代码来操作我们的数据库,但是呢?JDBC 编程的操作太复杂了,为什么会说 JDBC 操作复杂呢?看下面这段代码。

package com.example.mybatis20231226.Dao;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class UserDao {DataSource dataSource = null;public UserDao(DataSource dataSource) {this.dataSource = dataSource;}public void addUser() throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = dataSource.getConnection();String sql = "insert into user values (?,?,?);";statement = connection.prepareStatement(sql);statement.setString(2, "小明");statement.setInt(3, 0);statement.execute();} catch (SQLException e) {throw new RuntimeException(e);} finally {if (statement != null) {statement.close();}if (connection != null) {connection.close();}}}
}

使用 JDBC 操作,需要创建出 DataSource 数据源对象、Connection 对象、PrepareStatement 对象,甚至是 ResultSet 对象,并且在使用完这些资源之后还不能忘记释放掉这些资源,这些 JDBC 很多的操作都是重复的,所以就出现了能够简化 JDBC 操作的框架——MyBatis。

什么是MyBatis

MyBatis的发展历程可以追溯到2001年,当时Clinton Begin发起了一个名为iBATIS的开源项目。iBATIS最初是一个专注于密码软件开发的开源项目,但后来逐渐发展成为一个基于Java的持久层框架。

在2004年,Clinton将iBATIS的名字和源码捐赠给了Apache软件基金会,接下来的6年中,开源软件世界发生了巨大的变化,一切开发实践、基础设施、许可,甚至数据库技术都彻底改变了。

2010年,核心开发团队决定离开Apache软件基金会,并且将iBATIS改名为MyBatis。之后,MyBatis迁移到了Google Code,并在2013年11月再次迁移到了GitHub。

在功能上,MyBatis是一款优秀的支持自定义SQL查询、存储过程和高级映射的持久层框架。它消除了几乎所有的JDBC代码和参数的手动设置以及结果集的检索。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。使得数据持久层的设计更为灵活和高效。

这里是 MyBatis 的中文官方网站https://mybatis.net.cn/

在这里插入图片描述
在 Spring 中,三层架构分别是Controller(控制层)、Service(业务逻辑层)和Dao(数据访问层),我们的 MyBatis 就处于三层架构的 Dao 层。

在这里插入图片描述
简单来说,MyBatis 就是更简单完成程序和数据库交互的框架,也就是更简单的操作和读取数据库的工具。

MyBatis 入门

首先我们先通过一个使用了 MyBatis 框架的程序来看看 MyBatis 有多么的方便。

创建带有MyBatis框架的SpringBoot项目

在创建项目的时候勾选上 MyBatis FrameworkMySQL Driver

在这里插入图片描述
MyBatis 不是只能用于 Java 的 Spring 框架,它可以独立存在,只是因为 MyBatis 的实用性的方便,所以 Idea 才将 MyBatis 给集成进来了。那么既然选择了 MyBatis,为什么还要选择 MySQL Driver 呢?前面我们说了,MyBatis 是一种框架,他操作的是数据库,只是简化了 JDBC 的操作,所以底层还是 JDBC。

当勾选了 MyBatis 框架了之后,在 SpringBoot 项目的 pom.xml 文件中可以发现已经自动导入了 MyBatis 和 MySQL 的依赖。

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>3.0.3</version><scope>test</scope>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>

如果我们已经创建完成了SpringBoot项目了之后,想要在当前项目添加进去 MyBatis 依赖的话,可以使用前面的 Edit Starters 插件来继续添加进去 MyBatis 依赖。

在这里插入图片描述
当然我们也可以去 maven 中央仓库通过添加 MyBatis 依赖的坐标到 pom.xml 文件中来加入依赖,其实上一个在创建 SpringBoot 项目的时候勾选 MyBatis 选项也是将 MyBatis 的坐标添加进去 pom.xml 文件中,只不过这个是 Idea 帮我们自动完成了。

注意:手动添加 Mybatis 依赖的时候,需要注意 Spring 版本和 MyBatis 版本的对应关系。

数据准备

我们先在本地数据库中存储一些数据,作为后面 MyBatis 操作的数据。

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;-- 添加⽤⼾信息
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.userinfo ( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

在这里插入图片描述
在 Java 中创建出 UserInfo 类与数据库中一行的数据对应。这里为什么要与数据库中的列对应以及可不可以不对应,我们后面再说。

package com.example.mybatis20231226.Model;import lombok.Data;import java.util.Date;@Data
public class UserInfo {private int id;private String username;private String password;private int age;private int gender;private String phone;private int deleteFlag;private Date createTime;private Date updateTime;
}

在配置文件中配置数据库相关信息

我这里选择的是 YAML 配置文件配置,properties 也类似。

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: xxxxxxdriver-class-name: com.mysql.cj.jdbc.Driver

如果MySQL使用的是5.x之前版本的话,driver-class-name选项的值要使用 com.mysql.jdbc.Driver ,大于5.x版本就使用 com.mysql.jdbc.cj.Driver

实现持久层代码

MyBatis 持久层接口规范一般都叫XxxMapper。

package com.example.mybatis20231226.Mapper;import com.example.mybatis20231226.Model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface UserInfoMapper {@Select("select * from userinfo")public List<UserInfo> selectAll();
}

注意这里的 @Mapper 注解要选择 org.apache.ibatis.annotations 包下的。
在这里插入图片描述
在MyBatis中,@Mapper注解主要用于标识接口,它表示该接口是一个MyBatis的映射器接口。这个注解可以帮助简化代码和提高代码的可读性。

当你使用@Mapper注解标记一个接口时,MyBatis会自动为该接口生成实现类,该实现类包含了该接口中所有方法对应的SQL语句和执行逻辑。而在Spring中使用@Mapper注解,Spring会扫描到这个接口,并将其实例化为一个Bean,自动注入到MyBatis的SqlSession中。这样,你就可以通过直接调用接口方法的方式来执行相应的SQL语句,而不需要手动编写实现代码。

@Select("select * from userinfo")
public List<UserInfo> selectAll();

public List<UserInfo> selectAll() 是方法的声明,而这个 @Select("select * from userinfo") 则是这个方法的实现。Select 说明这个方法是一个查询方法。

那么有人会问了,这里类为什么会选择使用 interface 接口,而不是 class 呢?如果你是 class 的话,那么方法的具体实现就是需要我们写出来的,而上面说了这个方法的实现是通过 @Select("select * from userinfo") 注解实现的,如果我们再在这个方法中写上实现的话,就会导致冲突出现问题,而 interface 接口中的所有方法都是抽象方法,是不需要写出方法的实现的,正好对应 MyBatis 注解来实现,所以 interface 接口是最好的选择。

单元测试

当我们写完上面的代码之后,是否需要再创建一个测试类来测试这个方法呢?可以这样,但是这样比较麻烦,我们可以通过单元测试的方法快速的测试我们的代码功能。

单元测试是一种对软件中的最小可测试单元进行检查和验证的测试活动。在软件开发过程中,单元测试是在最低级别进行的测试活动,通常针对软件的独立单元进行,这些单元可能是函数、类、模块或组件。单元测试的目标是确保每个单元都能按照预期的方式工作,并且能够与其他单元协调工作。
对于单元测试中单元的含义,要根据实际情况去判定其具体含义。例如,在C语言中,单元通常指的是一个函数;在Java中,单元通常指的是一个类;在图形化的软件中,单元可能指的是一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。

我们在需要单元测试的类中右键选择generate。

在这里插入图片描述

选择 Test。

在这里插入图片描述
在这里插入图片描述
当点击ok之后,就会生成一个单元测试代码:

package com.example.mybatis20231226.Mapper;import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;@Slf4j
class UserInfoMapperTest {@BeforeEachvoid setUp() {}@AfterEachvoid tearDown() {}@Testvoid selectAll() {}
}

然后我们只需要完成单元测试中函数的实现的可以了。

package com.example.mybatis20231226.Mapper;import com.example.mybatis20231226.Model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;import java.util.List;import static org.junit.jupiter.api.Assertions.*;@Slf4j
class UserInfoMapperTest {//通过@Autowired注解拿到Bean@Autowiredprivate UserInfoMapper userInfoMapper;@BeforeEachvoid setUp() {log.info("selectAll 执行之前");}@AfterEachvoid tearDown() {log.info("selectAll 执行之后");}@Testvoid selectAll() {List<UserInfo> list = userInfoMapper.selectAll();log.info(list.toString());}
}

当我们运行会发现,运行出现了问题:

在这里插入图片描述

为什么会出现这种错误呢?出现这种错误就是因为 Spring 环境没有正确启动。所以我们需要在类上加上类注解 @SpringBootTest 来为这个类加上 Spring 上下文管理。

@SpringBootTest
@Slf4j
class UserInfoMapperTest {
}
package com.example.mybatis20231226.Mapper;import com.example.mybatis20231226.Model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;import static org.junit.jupiter.api.Assertions.*;@SpringBootTest
@Slf4j
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@BeforeEachvoid setUp() {log.info("selectAll 执行之前");}@AfterEachvoid tearDown() {log.info("selectAll 执行之后");}@Testvoid selectAll() {List<UserInfo> list = userInfoMapper.selectAll();log.info(list.toString());}
}

在这里插入图片描述

在这里插入图片描述
通过这种单元测试就达到了测试代码功能的作用,那么 MyBatis 的详细基础操作我就放在下一篇文章了。

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

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

相关文章

域名转移:将腾讯云转移至阿里云

当时注册域名时&#xff0c;腾讯域云相对便宜&#xff0c;但目前阿里云在业界更加成熟&#xff0c;因此将自己申请的域名由阿里云转移至阿里云&#xff0c;并记录转移过程。 一、域名转出 进入腾讯云&#xff0c;登陆后选择控制台&#xff0c;选择我的资源–域名注册–全部域名…

HarmonyOS4.0系统性深入开发11通过message事件刷新卡片内容

通过message事件刷新卡片内容 在卡片页面中可以通过postCardAction接口触发message事件拉起FormExtensionAbility&#xff0c;然后由FormExtensionAbility刷新卡片内容&#xff0c;下面是这种刷新方式的简单示例。 在卡片页面通过注册Button的onClick点击事件回调&#xff0c;…

按行依次处理数据的文件操作(C语言版)

按行依次处理数据的文件操作(C语言版) 这段代码的目的是处理多个文件&#xff0c;为每个文件创建一个新文件&#xff0c;将以 ‘r’ 开头的行添加 “./” 前缀&#xff0c;并将修改后的内容写入新文件。在main函数中&#xff0c;通过调用process函数&#xff0c;逐个处理了一系…

计算机网络——应用层与网络安全(六)

前言&#xff1a; 前几章我们已经对TCP/IP协议的下四层已经有了一个简单的认识与了解&#xff0c;下面让我们对它的最顶层&#xff0c;应用层进行一个简单的学习与认识&#xff0c;由于计算机网络多样的连接形式、不均匀的终端分布&#xff0c;以及网络的开放性和互联性等特征&…

使用ASP.NET MiniAPI 调试未匹配请求路径

本文将介绍如何在使用ASP.NET MiniAPI时调试未匹配到的请求路径。我们将详细讨论使用MapFallback方法、中间件等工具来解决此类问题。 1. 引言 ASP.NET MiniAPI是一个轻量级的Web API框架&#xff0c;它可以让我们快速地构建和部署RESTful服务。然而&#xff0c;在开发过程中如…

学习华为企业无线网络,有这篇文章就够了。

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; •以有线电缆或光纤作为传输介质的有线局域网应用广泛&#xff0c;但有线传输介质的铺设成本高&#xff0c;位置固定&#xff0c;移动性差。随着人们对…

固定本机在局域网中的 IP 地址

说明&#xff1a;以将 IP 地址固定为 192.168.1.107 为例 Step1、打开终端&#xff0c;输入以下命令查看网络信息&#xff1a; ipconfig -all 记住子网掩码、默认网关、DNS 服务器&#xff08;首选和备用&#xff09;信息&#xff0c;后面要用&#xff1a; Step2、进入 “控制…

分割数组的最大差值 - 华为OD统一考试

分割数组的最大差值 - 华为OD统一考试 OD统一考试 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 给定一个由若干整数组成的数组nums &#xff0c;可以在数组内的任意位置进行分割&#xff0c;将该数组分割成两个非空子数组(即左数组和右数组)&#xf…

小波理论与应用:理解小波

1 简介 来自源的信号通常处于时域。例如正弦信号、生物医学信号等。任何时域信号都可以使用数学变换进行处理或变换到频域&#xff08;谱域&#xff09;。傅里叶变换是一种流行或著名的变换&#xff0c;它将时域信号转换为频域信号&#xff0c;而不失一般性。 在绘制时域信号…

web:[BJDCTF2020]The mystery of ip(ssti模板注入、Smarty 模板引擎)

题目 进入页面显示如下 点击flag页面得到ip 点击hint页面 在hint.php的源代码页面中发现 由题目可以知道要从ip入手 这里尝试抓包加上X-Forwarded-For请求头修改为127.0.0.1 因为直接将127.0.0.1输出到页面&#xff0c;可以猜测是ssti模板注入 可以继续验证 这里发现输入什么…

动力学约束下的运动规划算法——Kinodynamic RRT*算法

一、RRT * 算法回顾 为了更好的理解Kinodynamic RRT*算法&#xff0c;我们先来回顾一下RRT * 算法 RRT * 先通过Sample函数随机选取一个点Xrand&#xff0c;然后通过Near函数找到当前树上距离Xrand最近的一个点Xnear&#xff0c;再通过Steer函数&#xff0c;沿着从Xnear到Xra…

pycharm python环境安装

目录 1.Python安装 2.PyQt5介绍 3.安装pyuic 4.启动designer.exe 5.pyinstaller(打包发布程序) 6.指定源安装 7.PyQt5-tools安装失败处理 8.控件介绍 9.错误记录 1.NameError: name reload is not defined 10.开发记录 重写报文输出和文件 ​编辑 1.Python安装 点…