【Java项目脚手架系列】第五篇:Spring Boot + MyBatis项目脚手架
前言
在前面的文章中,我们介绍了 Spring Boot 基础项目脚手架。今天,我们将介绍 Spring Boot + MyBatis 项目脚手架,这是一个用于快速搭建企业级应用的框架。
什么是 Spring Boot + MyBatis?
Spring Boot + MyBatis 是一个强大的组合,它提供了:
- Spring Boot 的快速开发能力
- MyBatis 的灵活 SQL 映射
- 完整的数据库操作支持
- 事务管理能力
- 测试框架支持
技术栈
- Spring Boot 2.7.18:核心框架
- MyBatis 3.5.15:持久层框架
- MySQL 8.0:关系型数据库
- H2 Database:内存数据库,用于测试
- JUnit 5:测试框架
- Mockito:测试框架
- Maven 3.9.6:项目构建工具
Spring Boot + MyBatis 项目脚手架
1. 项目结构
src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── demo
│ │ ├── DemoApplication.java
│ │ ├── config
│ │ │ └── MyBatisConfig.java
│ │ ├── controller
│ │ │ └── UserController.java
│ │ ├── mapper
│ │ │ └── UserMapper.java
│ │ ├── model
│ │ │ ├── entity
│ │ │ │ └── User.java
│ │ │ └── vo
│ │ │ └── UserVO.java
│ │ └── service
│ │ ├── UserService.java
│ │ └── impl
│ │ └── UserServiceImpl.java
│ └── resources
│ ├── application.yml
│ ├── db
│ │ └── init.sql
│ └── mapper
│ └── UserMapper.xml
└── test
├── java
│ └── com
│ └── example
│ └── demo
│ ├── config
│ │ └── TestConfig.java
│ ├── controller
│ │ └── UserControllerTest.java
│ ├── mapper
│ │ └── UserMapperTest.java
│ └── service
│ └── UserServiceTest.java
└── resources
└── application-test.yml
2. 核心文件内容
2.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot-mybatis-scaffold</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- H2 Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Spring Boot DevTools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2 DemoApplication.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.3 UserController.java
package com.example.demo.controller;
import com.example.demo.model.vo.UserVO;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public UserVO getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
@GetMapping
public List<UserVO> getAllUsers() {
return userService.getAllUsers();
}
@PostMapping
public UserVO createUser(@RequestBody UserVO userVO) {
return userService.createUser(userVO);
}
@PutMapping("/{id}")
public UserVO updateUser(@PathVariable Long id, @RequestBody UserVO userVO) {
return userService.updateUser(id, userVO);
}
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
2.4 UserService.java
package com.example.demo.service;
import com.example.demo.model.vo.UserVO;
import java.util.List;
public interface UserService {
UserVO getUserById(Long id);
List<UserVO> getAllUsers();
UserVO createUser(UserVO userVO);
UserVO updateUser(Long id, UserVO userVO);
void deleteUser(Long id);
}
2.5 application.yml
# Server Configuration
server:
port: 8080
servlet:
context-path: /api
# Application Name
spring:
application:
name: springboot-mybatis-scaffold
datasource:
url: jdbc:mysql://localhost:3306/demo
username: your_username
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
# MyBatis Configuration
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.demo.model.entity
# Logging Configuration
logging:
level:
root: INFO
com.example.demo: DEBUG
3. 使用说明
-
克隆项目
git clone git@gitee.com:zengqiang_wang/leecode-inteview-questions-journal.git
-
导入IDE
- 推荐使用 IntelliJ IDEA
- 选择 “Open as Maven Project”
- 等待 Maven 依赖下载完成
-
初始化数据库
- 创建数据库:
demo
- 执行
src/main/resources/db/init.sql
脚本 - 修改数据库连接配置
- 创建数据库:
-
运行项目
mvn spring-boot:run
-
访问接口
- 创建用户:POST http://localhost:8080/api/users
- 查询用户:GET http://localhost:8080/api/users/
- 更新用户:PUT http://localhost:8080/api/users/
- 删除用户:DELETE http://localhost:8080/api/users/
- 用户列表:GET http://localhost:8080/api/users
-
运行测试
# 运行所有测试 mvn test # 运行特定测试类 mvn test -Dtest=UserControllerTest # 运行特定测试方法 mvn test -Dtest=UserControllerTest#testGetUserById
4. 单元测试
项目包含了完整的单元测试示例,展示了如何测试 Spring Boot + MyBatis 应用的不同组件:
-
服务层测试
- 使用 JUnit 5 进行基础单元测试
- 使用 Mockito 模拟依赖
- 测试正常和边界情况
- 示例:
UserServiceTest.java
-
Mapper 层测试
- 使用 H2 内存数据库
- 测试数据库操作
- 事务自动回滚
- 示例:
UserMapperTest.java
-
控制器层测试
- 使用 MockMvc 测试 HTTP 接口
- 验证请求和响应
- 示例:
UserControllerTest.java
5. 最佳实践
-
控制器设计
- 使用 RESTful 风格
- 合理使用请求方法
- 统一响应格式
- 参数验证
-
服务层设计
- 业务逻辑封装
- 事务管理
- 异常处理
- 数据转换
-
数据访问层设计
- 使用 MyBatis 注解或 XML
- 动态 SQL 支持
- 分页查询
- 缓存配置
-
配置管理
- 使用配置文件
- 环境隔离
- 敏感信息保护
- 数据库连接池
6. 常见问题
-
数据库连接问题
- 检查数据库配置
- 确保数据库服务运行
- 验证用户名密码
- 检查连接池配置
-
MyBatis 配置问题
- 检查 Mapper 扫描路径
- 验证 XML 文件位置
- 确认 SQL 语句正确性
- 检查类型别名配置
-
事务管理问题
- 检查事务注解
- 验证事务传播行为
- 确认事务隔离级别
- 处理事务回滚
-
MySQL 相关问题
-
问题:本地未安装 MySQL
- 原因:开发环境缺少 MySQL 数据库
- 解决方案:
- 安装 MySQL 8.0
- 或使用 Docker 运行 MySQL:
docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:8.0
- 或使用 H2 数据库替代(仅用于开发环境)
-
问题:MySQL 连接失败
- 原因:MySQL 服务未启动或配置错误
- 解决方案:
spring: datasource: url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: your_username password: your_password
-
-
H2 数据库问题
-
问题:表名冲突
- 原因:
user
是 H2 数据库的保留关键字 - 解决方案:将表名改为
t_user
或其他非保留关键字 - 示例:
-- 修改前 CREATE TABLE user ( id BIGINT PRIMARY KEY, username VARCHAR(50) ); -- 修改后 CREATE TABLE t_user ( id BIGINT PRIMARY KEY, username VARCHAR(50) );
- 原因:
-
问题:SQL 语法不兼容
- 原因:H2 与 MySQL 的 SQL 语法存在差异
- 解决方案:
- 在 H2 连接 URL 中添加 MySQL 兼容模式:
spring: datasource: url: jdbc:h2:mem:testdb;MODE=MySQL;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE
- 使用 H2 兼容的 SQL 语法
- 为测试环境准备单独的 SQL 文件
- 在 H2 连接 URL 中添加 MySQL 兼容模式:
-
问题:测试数据未持久化
- 原因:H2 内存数据库在应用重启后数据会丢失
- 解决方案:
- 使用文件模式而不是内存模式
- 在测试类中初始化测试数据
- 使用
@Transactional
确保测试数据回滚
-
问题:H2 控制台访问失败
- 原因:H2 控制台未启用或配置错误
- 解决方案:
spring: h2: console: enabled: true path: /h2-console datasource: url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1 username: sa password:
-
-
开发环境配置建议
- 使用 H2 数据库进行本地开发
- 配置多环境支持
- 分离开发和生产配置
- 使用 Docker 容器化数据库
总结
Spring Boot + MyBatis 脚手架提供了一个完整的企业级应用开发基础,包含了必要的配置和示例代码。通过这个项目,你可以:
- 快速搭建 Web 应用
- 实现数据库操作
- 进行单元测试
- 使用开发工具
明日预告
明天我们将介绍 Spring Boot + JPA 项目脚手架,主要内容包括:
- JPA 与 Spring Boot 的集成
- 实体关系映射
- 数据访问层设计
- 事务管理
- 分页查询实现
- 单元测试示例
敬请期待!