辽宁建设执业继续教育协会网站,做网站有什么工具,深圳网站建设制作网络公司,河南郑州金水区文章目录 为什么要学习MyBatis什么是MyBatisMyBatis 入门创建带有MyBatis框架的SpringBoot项目数据准备在配置文件中配置数据库相关信息实现持久层代码单元测试 为什么要学习MyBatis
前面我们肯定多多少少学过 sql 语言#xff0c;sql 语言是一种操作数据库的一类语言#x… 文章目录 为什么要学习MyBatis什么是MyBatisMyBatis 入门创建带有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的POJOsPlain Old Java Objects普通的Java对象映射成数据库中的记录。使得数据持久层的设计更为灵活和高效。
这里是 MyBatis 的中文官方网站https://mybatis.net.cn/ 在 Spring 中三层架构分别是Controller控制层、Service业务逻辑层和Dao数据访问层我们的 MyBatis 就处于三层架构的 Dao 层。 简单来说MyBatis 就是更简单完成程序和数据库交互的框架也就是更简单的操作和读取数据库的工具。
MyBatis 入门
首先我们先通过一个使用了 MyBatis 框架的程序来看看 MyBatis 有多么的方便。
创建带有MyBatis框架的SpringBoot项目
在创建项目的时候勾选上 MyBatis Framework 和 MySQL Driver MyBatis 不是只能用于 Java 的 Spring 框架它可以独立存在只是因为 MyBatis 的实用性的方便所以 Idea 才将 MyBatis 给集成进来了。那么既然选择了 MyBatis为什么还要选择 MySQL Driver 呢前面我们说了MyBatis 是一种框架他操作的是数据库只是简化了 JDBC 的操作所以底层还是 JDBC。
当勾选了 MyBatis 框架了之后在 SpringBoot 项目的 pom.xml 文件中可以发现已经自动导入了 MyBatis 和 MySQL 的依赖。
dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter-test/artifactIdversion3.0.3/versionscopetest/scope
/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/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?characterEncodingutf8useSSLfalseusername: 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 ListUserInfo selectAll();
}
注意这里的 Mapper 注解要选择 org.apache.ibatis.annotations 包下的。 在MyBatis中Mapper注解主要用于标识接口它表示该接口是一个MyBatis的映射器接口。这个注解可以帮助简化代码和提高代码的可读性。
当你使用Mapper注解标记一个接口时MyBatis会自动为该接口生成实现类该实现类包含了该接口中所有方法对应的SQL语句和执行逻辑。而在Spring中使用Mapper注解Spring会扫描到这个接口并将其实例化为一个Bean自动注入到MyBatis的SqlSession中。这样你就可以通过直接调用接口方法的方式来执行相应的SQL语句而不需要手动编写实现代码。
Select(select * from userinfo)
public ListUserInfo selectAll();public ListUserInfo 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注解拿到BeanAutowiredprivate UserInfoMapper userInfoMapper;BeforeEachvoid setUp() {log.info(selectAll 执行之前);}AfterEachvoid tearDown() {log.info(selectAll 执行之后);}Testvoid selectAll() {ListUserInfo 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() {ListUserInfo list userInfoMapper.selectAll();log.info(list.toString());}
}通过这种单元测试就达到了测试代码功能的作用那么 MyBatis 的详细基础操作我就放在下一篇文章了。