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

news2024/11/30 6:56:51

在这里插入图片描述

文章目录

  • 为什么要学习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=false
    username: root
    password: xxxxxx
    driver-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 {

    @BeforeEach
    void setUp() {
    }

    @AfterEach
    void tearDown() {
    }

    @Test
    void 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
    @Autowired
    private UserInfoMapper userInfoMapper;
    @BeforeEach
    void setUp() {
        log.info("selectAll 执行之前");
    }

    @AfterEach
    void tearDown() {
        log.info("selectAll 执行之后");
    }

    @Test
    void 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 {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @BeforeEach
    void setUp() {
        log.info("selectAll 执行之前");
    }

    @AfterEach
    void tearDown() {
        log.info("selectAll 执行之后");
    }

    @Test
    void selectAll() {
        List<UserInfo> list = userInfoMapper.selectAll();
        log.info(list.toString());
    }
}

在这里插入图片描述

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

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

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

相关文章

BLE Mesh蓝牙组网技术详细解析之Lower Transport Layer下传输层(四)

目录 一、什么是BLE Mesh Lower Transport Layer下传输层&#xff1f; 二、未分段消息 2.1 未分段接入层消息 2.2 未分段控制层消息 三、分段消息 3.1 超过多少个字节需要分段&#xff1f; 3.2 分段接入层消息 3.3 分段控制层消息 3.4 分段确认消息 3.5 分段和重组流程…

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

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

牛客网SQL训练5—SQL大厂面试真题

文章目录 一、某音短视频1.各个视频的平均完播率2.平均播放进度大于60%的视频类别3.每类视频近一个月的转发量/率4.每个创作者每月的涨粉率及截止当前的总粉丝量5.国庆期间每类视频点赞量和转发量6.近一个月发布的视频中热度最高的top3视频 二、用户增长场景&#xff08;某度信…

[react]脚手架create-react-app/vite与reac项目

[react]脚手架create-react-app/vite与reac项目 环境问题描述create-react-app 脚手架根据脚手架修改项目结构安装脚手架注入配置文件-config文件夹package.json文件变更删除 serviceWorker.js新增reportWebVitals.js文件更新index.js文件 脚手架creat-react-app 缺点 vite 脚手…

数据结构期末复习(2)链表

链表 链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列具有相同类型的元素。链表由节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两部分&#xff1a;数据域&#xff08;存储元素值&#xff09;和指针域&#xff08;指…

MyBatis多表映射

1. 多表映射概念 MyBatis 思想是&#xff1a;数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式&#xff0c;可惜它们并不都是那样。 如果能有一种数据库映射模式&#xff0c;完美适配所有的应用程序查询需求&#xff0c;那就太…

【FileZilla的安装与使用(主动与被动模式详解,以及如何利用FileZilla搭建FTP服务器并且进行访问)】

目录 一、FileZilla介绍 1.1 简介 1.2 重要信息和功能 二、FileZilla的安装与使用 2.1 FileZilla服务端安装与配置 2.1.1 安装步骤 2.1.2 新建组 2.1.3 新建用户 2.1.4 新建目录 2.1.5 权限分配 &#xff08;1&#xff09;用户Milk权限分配 &#xff08;2&#xff…

HikvisionCamera开发-萤石云RTMP协议获取视频流

RTMP/RTSP&#xff08;实时流传输协议&#xff09;是一种网络协议&#xff0c;旨在用于传输音频和视频数据。本文将介绍如何在HikvisionCamera二次开发中如何通过RTMP协议获得实时视频流&#xff0c;使用到的摄像头为POE供电的海康威视-臻全彩款&#xff0c;以及套餐内配套录像…

JMeter使用

目录 启动JMeter 创建线程组 设置线程参数 设置http请求参数 ​编辑 创建查看结果树(显示成功/失败多少以及返回结果等信息) 创建聚合报告(显示响应时间、吞吐量、异常数等信息) 点击上方的执行按钮即可开始压力测试 结果树显示 聚合报告结果显示 启动JMeter 在JMete…

【NLP论文】03 基于 jiagu 的情感分析

本篇是NLP论文系列的最后一篇&#xff0c;主要介绍如何计算情感分析结果&#xff0c;并将其融入到XX评价体系和物流关键词词库&#xff0c;之前我已经写了两篇关于情感分析的文章&#xff0c;分别是 SnowNLP 和 Cemotion 技术&#xff0c;最终我才用了 jiagu 来写我的论文&…

机器人中的数值优化之线性共轭梯度法

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》 目录 1.无约束优化方法对比 2.Hessian-vec product 3.线性共轭梯度方法的步长​编辑 4.共轭梯度…

mac上使用Navicat Premium 在本地和生产环境中保持数据库同步

Navicat Premium 是一款功能强大的数据库管理和开发工具&#xff0c;支持多种数据库系统&#xff0c;如 MySQL、Oracle、SQL Server 等。作为程序员&#xff0c;我深知在开发过程中需要一款方便、高效的数据库管理工具来提升工作效率。而 Navicat Premium 正是这样一款不可多得…

Spring Boot学习随笔- Jasypt加密数据库用户名和密码以及解密

学习视频&#xff1a;【编程不良人】2021年SpringBoot最新最全教程 第十九章、Jasypt加密 Jasypt全称是Java Simplified Encryption&#xff0c;是一个开源项目。 Jasypt与Spring Boot集成&#xff0c;以便在应用程序的属性文件中加密敏感信息&#xff0c;然后在应用程序运行…

怎么解决 Nginx反向代理加载速度慢?

Nginx反向代理加载速度慢可能由多种原因引起&#xff0c;以下是一些可能的解决方法&#xff1a; 1&#xff0c;网络延迟&#xff1a; 检查目标服务器的网络状况&#xff0c;确保其网络连接正常。如果目标服务器位于不同的地理位置&#xff0c;可能会有较大的网络延迟。考虑使用…

从0到1快速入门ETLCloud

一、ETLCloud的介绍 ETL是将业务系统的数据经过抽取&#xff08;Extract&#xff09;、清洗转换&#xff08;Transform&#xff09;之后加载&#xff08;Load&#xff09;到数据仓库的过程&#xff0c;目的是将企业中的分散、凌乱、标准不统一的数据整合到一起&#xff0c;为企…

【C#】知识点实践序列之Lock的输出多线程信息

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂之知识点实践序列》文章。 2023年第2篇文章&#xff0c;此篇文章是C#知识点实践序列之Lock知识点&#xff0c;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 本篇在Lock锁定代码…

【力扣题解】P700-二叉搜索树中的搜索-Java题解

&#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【力扣题解】 文章目录 【力扣题解】P700-二叉搜索树中的搜索-Java题解&#x1f30f;题目描述&#x1f4a1;题解&#x1f…

D45D46|动态规划之子序列问题

300.最长递增子序列&#xff1a; 初始思路&#xff1a; 动态规划五部曲&#xff1a; 1&#xff09;dp数组的定义&#xff0c;dp[i]表述数组第i个元素大于前面几个值&#xff1b; 2&#xff09;dp数组的迭代&#xff0c;min nums[x]表示递增数组中的最后一个值&#xff0c;如…

Linux 安装 mysql【使用yum源进行安装】

配置yum 源 首先&#xff0c;去到mysql网站&#xff0c;找到它的rpm的资源包 “mysql80-community-release-el9-5.noarch.rpm” 我们将其下载下来&#xff0c;然后配置yum源&#xff08;下面两种方式二选一即可&#xff09; ① 使用xftp传输&#xff0c;然后配置yum源 rpm …

【数据结构】栈和队列(队列的基本操作和基础知识)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 ​ 目录 前言 队列 队列的概念和结构 队列的…