网站制做工具,php做视频分享网站,车都建设投资集团网站,专业的网络公司介绍大家好#xff0c;我是磊磊落落#xff0c;目前我在技术上主要关注#xff1a;Java、Golang、架构设计、云原生和自动化测试。欢迎来我的博客#xff08;leileiluoluo.com#xff09;获取我的最近更新#xff01; 本文原始链接#xff1a;https://leileiluoluo.com/post… 大家好我是磊磊落落目前我在技术上主要关注Java、Golang、架构设计、云原生和自动化测试。欢迎来我的博客leileiluoluo.com获取我的最近更新 本文原始链接https://leileiluoluo.com/posts/spring-boot-mybatis-integration.html
MyBatis 是一个适用于 Java 语言的持久层框架。MyBatis 支持以注解或 XML 配置的方式来定义 SQL 查询以及查询结果和 Java 对象的映射。MyBatis 相比于 Java 另一个流行持久层框架 JPA 来说具体使用请参看「如何使用 Spring Data JPA 进行数据库访问 」最大的特点是 MyBatis 具有更灵活的 SQL 控制能力。
本文以一个使用 Maven 管理的 Spring Boot 工程为例结合本地搭建的 MySQL 数据库版本为 8.1.0来演示 Spring Boot 与 MyBatis 的集成。
下面列出示例工程所使用的 JDK、Maven、Spring Boot 与 MyBatis Starter 的版本
JDKAmazon Corretto 17.0.8
Maven3.9.2
Spring Boot3.2.3
Mybatis Spring Boot Starter3.0.3接下来我们以实现 User 的增、删、改、查为例来探索 MyBatis 的使用。
1 准备测试数据
首先在本地 MySQL 数据库执行如下 SQL 来创建一个测试数据库、创建一个 user 表并在 user 表插入 3 条测试数据
CREATE DATABASE test DEFAULT CHARSET utf8 COLLATE utf8_general_ci;DROP TABLE IF EXISTS user;
CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY,email VARCHAR(100) NOT NULL,name VARCHAR(100) NOT NULL,role ENUM(ADMIN, EDITOR, VIEWER) DEFAULT VIEWER,description VARCHAR(300) NOT NULL,created_at TIMESTAMP NOT NULL DEFAULT 2024-01-01 00:00:00,updated_at TIMESTAMP NOT NULL DEFAULT 2024-01-01 00:00:00,deleted BOOLEAN DEFAULT FALSE
);INSERT INTO user(email, name, role, description, created_at, updated_at, deleted) VALUES(larrylarry.com, Larry, ADMIN, I am Larry, 2024-01-01 08:00:00, 2024-01-01 08:00:00, false),(jackyjacky.com, Jacky, EDITOR, I am Jacky, 2024-02-01 08:00:00, 2024-02-01 08:00:00, false),(lucylucy.com, Lucy, VIEWER, I am Lucy, 2024-03-01 08:00:00, 2024-03-01 08:00:00, false);2 开始使用 MyBatis
测试数据准备好后即可以尝试使用 MyBatis 了。
2.1 POM 依赖项
如下为本文示例工程 pom.xml 的配置信息
!-- pom.xml --
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.3/versionrelativePath//parentgroupIdcom.example/groupIdartifactIdspring-boot-mybatis-integration-demo/artifactIdversion0.0.1-SNAPSHOT/versionpropertiesjava.version17/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion3.0.3/version/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdversion8.3.0/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.30/version/dependency!-- testing --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-api/artifactIdversion5.10.2/versionscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfigurationsource17/sourcetarget17/target/configuration/plugin/plugins/build
/project可以看到本工程基于 Java 17使用的 Spring Boot 版本为 3.2.3用到的依赖有 spring-boot-starter-web、mybatis-spring-boot-starter、mysql-connector-j 和 lombok。
2.2 application.yaml 配置
如下为 application.yaml 文件的配置信息
# src/main/resources/application.xml
spring:datasource:url: jdbc:mysql://localhost:3306/test?autoReconnecttrueuseUnicodetruecharacterEncodingutf-8serverTimezoneGMT%2B8username: rootpassword: root
mybatis:mapper-locations: classpath:mapper/*Mapper.xml
logging:level:com.example.demo.dao.UserDaoMapper: DEBUG可以看到我们使用了 Spring Boot 的标准配置方式来指定数据库的连接信息。针对 MyBatis 的配置部分我们使用 mybatis.mapper-locations 指定了 MyBatis Mapper 文件的路径。此外还将接下来要编写的 Mapper 接口的日志级别定义为了 DEBUG以便在控制台打印对应的 SQL。
2.3 Java POJO 类
如下为 User Model 类的内容
// src/main/java/com/example/demo/model/User.java
package com.example.demo.model;import lombok.Data;import java.util.Date;Data
public class User {private Long id;private String email;private String name;private Role role;private String description;private Date createdAt;private Date updatedAt;private Boolean deleted;public enum Role {ADMIN,EDITOR,VIEWER}
}可以看到我们为数据库表 user 新建了对应的 Model 类 User.java该类中各个字段的含义与类型与前面的建表语句一一对应。
2.4 Mapper 接口
接下来我们定义一个接口 UserDaoMapper.java针对 User 的增、删、改、查方法均定义于其中
// src/main/java/com/example/demo/dao/UserDaoMapper.java
package com.example.demo.dao;import com.example.demo.model.User;import java.util.List;public interface UserDaoMapper {ListUser list(int offset, int rows);long count();User getById(Long id);boolean existsByEmail(String email);ListUser searchByName(String name);void save(User user);void batchSave(ListUser users);void update(User user);void deleteById(Long id);
}可以看到我们针对 User 定义了分页列表查询list、总数查询count、单条查询getById、根据邮箱判断是否存在existsByEmail、根据名称搜索searchByName、批量保存batchSave、更新update、单条删除deleteById等各种常用方法。
2.5 Mapper XML 配置文件
下面即是本文最关键的部分MyBatis Mapper 文件的配置。该文件用于配置上一部分 UserDaoMapper 接口中定义的各种方法的具体 SQL 语句以及接收查询结果的类型或对象。
UserDaoMapper.xml 的内容如下
!-- src/main/resources/mapper/UserDaoMapper.xml --
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.dao.UserDaoMappersql idinsert_columnsemail,name,role,description,created_at,updated_at,deleted/sqlsql idselect_columnsid,email,name,role,description,created_at as createdAt,updated_at as updatedAt,deleted/sqlselect idlist resultTypecom.example.demo.model.UserSELECTinclude refidselect_columns/FROM userWHERE deleted falseORDER BY created_at DESCLIMIT #{offset}, #{rows}/selectselect idcount resultTypelongSELECTCOUNT(*)FROM userWHERE deleted false/selectselect idgetById resultTypecom.example.demo.model.UserSELECTinclude refidselect_columns/FROM userWHERE deleted falseAND id #{id}/selectselect idexistsByEmail resultTypebooleanSELECTEXISTS (SELECT 1FROM userWHERE deleted falseAND email #{email})/selectselect idsearchByName resultTypecom.example.demo.model.UserSELECTinclude refidselect_columns/FROM userWHERE deleted falseif testname ! null and name ! AND name LIKE CONCAT(%, #{name}, %)/if/selectinsert idsave useGeneratedKeystrue keyPropertyidINSERT INTO user (include refidinsert_columns/) VALUES (#{email},#{name},#{role},#{description},now(),now(),false)/insertinsert idbatchSave useGeneratedKeystrue keyPropertyidINSERT INTO user (include refidinsert_columns/) VALUESforeach itemitem collectionlist separator,(#{item.email}, #{item.name}, #{item.role}, #{item.description}, now(), now(), false)/foreach/insertupdate idupdateUPDATE userSETemail #{email},name #{name},role #{role},description #{description},updated_at now()WHERE id #{id}/updatedelete iddeleteByIdDELETEFROM userWHERE id #{id}/delete
/mapper可以看到我们在该配置文件中使用 namespace 指定了其是 UserDaoMapper.java 的实现。且对接口中定义的增、删、改、查方法分别使用标签 insert、delete、update、select 定义了具体的 SQL 语句。对于这些 SQL 语句我们使用 sql 来抽取了共用的片段。此外还使用了 foreach 和 if 标签。此外对于插入与批量插入我们还使用对应的配置useGeneratedKeystrue keyPropertyid实现了插入后自增 ID 的自动设置。
2.6 单元测试
到目前为止我们的数据库连接配置、Model 类、查询接口、Mapper 配置均已编写好了。下面即对 UserDaoMapper 接口编写一个单元测试类来测试一下其功能
// src/test/java/com/example/demo/dao/UserDaoMapperTest.java
package com.example.demo.dao;import com.example.demo.model.User;
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
public class UserDaoMapperTest {Autowiredprivate UserDaoMapper userDaoMapper;Testpublic void testList() {ListUser users userDaoMapper.list(2, 10);// assertionassertFalse(users.isEmpty());}Testpublic void testCount() {long count userDaoMapper.count();// assertionassertTrue(count 0);}Testpublic void testGetById() {User user userDaoMapper.getById(1L);// assertionassertNotNull(user);}Testpublic void testExistsByEmail() {boolean exists userDaoMapper.existsByEmail(larrylarry.com);// assertionassertTrue(exists);}Testpublic void testSearchByName() {ListUser users userDaoMapper.searchByName(La);// assertionassertFalse(users.isEmpty());}Testpublic void testSave() {User user new User();user.setEmail(daviddavid.com);user.setName(David);user.setRole(User.Role.VIEWER);user.setDescription(I am David);// saveuserDaoMapper.save(user);// assertionassertNotNull(user.getId());}Testpublic void testBatchSave() {User user1 new User();user1.setEmail(rossross.com);user1.setName(Ross);user1.setRole(User.Role.EDITOR);user1.setDescription(I am Ross);User user2 new User();user2.setEmail(lindalinda.com);user2.setName(Linda);user2.setRole(User.Role.VIEWER);user2.setDescription(I am Linda);ListUser users List.of(user1, user2);// batch saveuserDaoMapper.batchSave(users);// assertionusers.forEach(user - assertNotNull(user.getId()));}Testpublic void testUpdate() {User user userDaoMapper.getById(1L);user.setRole(User.Role.EDITOR);user.setDescription(Hello, I am Larry!);// updateuserDaoMapper.update(user);}Testpublic void testDeleteById() {userDaoMapper.deleteById(1L);}
}可以看到UserDaoMapper 接口的各个方法提供的功能均运行正常符合我们的预期。
综上我们完成了 Spring Boot 与 MyBatis 的集成了解了 MyBatis 基础功能的使用。完整示例工程已提交至本人 GitHub欢迎关注或 Fork。 参考资料 [1] MyBatis 3 Reference Documentation - https://mybatis.org/mybatis-3/ [2] What is MyBatis-Spring-Boot-Starter? - https://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/