SpringBoot 多人协作平台实战(5):从零开始集成 MyBatis ORM 连接 MySQL 数据库
本文是《Java SpringBoot 多人协作平台》系列实战课程的第五篇。前几节课我们完成了 SpringBoot 项目的基础搭建,本节将重点介绍如何通过 ORM 框架(MyBatis)连接 MySQL 数据库,并实现一个完整的数据查询链路:从数据库 → Mapper → Service → Controller → HTTP 响应。
一、什么是 ORM?
ORM(Object-Relational Mapping,对象关系映射)是一种将数据库表与 Java 对象自动映射的技术,开发者无需手动处理 JDBC 连接、结果集解析等底层细节,只需关注业务逻辑。
Java 生态中常见的 ORM 框架:
| 框架 | 特点 |
|---|---|
| JPA(Hibernate) | 全自动 ORM,无需手写 SQL,适合简单 CRUD 场景 |
| MyBatis | 半自动 ORM,需手写 SQL,灵活可控,适合复杂查询 |
本节课选用 MyBatis,它与 SpringBoot 的集成非常成熟,且对 SQL 的控制力更强,适合生产项目使用。
二、安装 MySQL 数据库
推荐使用 Docker 安装
为避免本地环境的版本冲突和配置烦恼,强烈推荐使用 Docker 启动 MySQL 实例:
ini
docker run -d \
--name mysql \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=xdml \
mysql
参数说明:
-d:后台运行容器--name mysql:容器命名为mysql-p 3306:3306:映射宿主机端口到容器端口-e MYSQL_ROOT_PASSWORD=123456:设置 root 密码-e MYSQL_DATABASE=xdml:自动创建名为xdml的数据库
三、初始化数据库表结构
3.1 创建用户表
连接到 MySQL 后,执行以下 DDL 语句创建 user 表:
sql
CREATE TABLE `user` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
`name` VARCHAR(50) NOT NULL COMMENT '用户名'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
AUTO_INCREMENT:主键自增,无需手动维护 IDutf8mb4:支持完整 Unicode,包括 emoji,推荐生产环境统一使用
3.2 插入测试数据
sql
INSERT INTO `user` (`name`) VALUES
('张三'), ('李四'), ('王五'), ('赵六'), ('陈七'),
('刘八'), ('周九'), ('吴十'), ('小明'), ('小红');
执行后表中将有 10 条测试记录,id 从 1 自动递增。
四、SpringBoot 集成 MyBatis
4.1 添加 Maven 依赖
在 pom.xml 中引入 mybatis-spring-boot-starter:
xml
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis-spring-boot-starter.version}</version>
</dependency>
版本号通过 ${mybatis-spring-boot-starter.version} 属性统一管理,建议在 <properties> 中声明,便于维护。
同时确保已引入 MySQL JDBC 驱动:
xml
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
4.2 配置数据源
修改 src/main/resources/application.properties,添加数据库连接信息:
ini
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xdml?useSSL=false&serverTimezone=UTC
注意 :useSSL=false 用于关闭 SSL 验证(本地开发环境),生产环境应启用 SSL;serverTimezone=UTC 可避免时区问题导致的连接报错。
五、定义实体类
在 hello.service 包下创建 User 实体类,用于映射数据库中的 user 表:
typescript
package hello.service;
public class User {
private Integer id;
private String name;
// Getter & Setter
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
MyBatis 默认通过字段名与列名进行映射,字段名与列名一致时无需额外配置。
六、创建 Mapper 接口
Mapper 是 MyBatis 的核心组件,负责定义 SQL 与 Java 方法的绑定关系。在 mapper 包下创建 UserMapper:
kotlin
package mapper;
import hello.service.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User findUserById(@Param("id") Integer id);
}
关键注解说明:
@Mapper:标识该接口为 MyBatis Mapper,Spring 会自动为其生成代理实现类@Select:注解方式直接在接口方法上绑定 SQL 查询语句@Param("id"):将方法参数绑定到 SQL 中的#{id}占位符
七、编写 Service 层
Service 层封装业务逻辑,通过构造函数注入 UserMapper:
kotlin
package hello.service;
import mapper.UserMapper;
import javax.inject.Inject;
public class UserService {
private final UserMapper userMapper;
@Inject
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
public User getUserById(Integer id) {
return userMapper.findUserById(id);
}
}
这里使用 javax.inject.@Inject 进行构造函数注入,与 Spring 的 @Autowired 效果一致,但属于标准 JSR-330 规范,具备更好的框架无关性。
八、配置 Spring Bean(JavaConfiguration)
在 JavaConfiguration 类中,通过 @Bean 方法手动注册 UserService,并使用 @MapperScan 扫描 Mapper 包:
kotlin
package hello.configuration;
import hello.service.OrderService;
import hello.service.UserService;
import mapper.UserMapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("mapper") // 扫描 mapper 包下的所有 Mapper 接口
public class JavaConfiguration {
@Bean
public UserService userService(UserMapper userMapper) {
return new UserService(userMapper);
}
@Bean
public OrderService orderService(UserService userService) {
return new OrderService(userService);
}
}
@MapperScan("mapper") 会自动扫描指定包下所有带 @Mapper 注解的接口,并将其注册为 Spring Bean,从而可以通过依赖注入的方式在 @Bean 方法参数中直接使用 UserMapper。
九、Controller 层测试
修改 HelloController,添加一个根路径接口,调用 UserService 查询 id 为 1 的用户:
kotlin
package hello;
import hello.service.User;
import hello.service.UserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.inject.Inject;
@RestController
public class HelloController {
private UserService userService;
@Inject
public HelloController(UserService userService) {
this.userService = userService;
}
@GetMapping("/hello")
public String sayHello() {
return "Hello, SpringBoot! 🎉";
}
@RequestMapping("/")
public User index() {
return this.userService.getUserById(1);
}
}
@RestController 会自动将返回值序列化为 JSON,因此访问 / 时将直接返回 User 对象的 JSON 表示。
十、验证结果
启动 SpringBoot 应用后,在浏览器或 HTTP 工具中访问:
arduino
http://localhost:8080/
如果一切配置正确,将看到如下 JSON 响应:
json
{
"id": 1,
"name": "张三"
}
这说明整条链路已经完整打通:HTTP 请求 → Controller → Service → MyBatis Mapper → MySQL → JSON 响应。
十一、整体架构回顾
markdown
HTTP 请求
│
▼
HelloController ← 接收请求,调用 Service
│
▼
UserService ← 封装业务逻辑,调用 Mapper
│
▼
UserMapper(MyBatis) ← 执行 SQL,映射结果集
│
▼
MySQL 数据库(Docker) ← 存储数据
总结
本节课我们完成了以下内容:
- 使用 Docker 快速启动 MySQL,避免本地环境配置问题
- 初始化数据库表并插入测试数据
- 集成
mybatis-spring-boot-starter,配置数据源连接信息 - 通过注解方式(
@Select)编写UserMapper - 在
JavaConfiguration中使用@MapperScan注册 Mapper 并手动装配 Bean - 通过
UserService和HelloController完成完整的查询链路验证
系列课程:Java SpringBoot 多人协作平台实战 · 第五章 · 从零开始利用ORM连接MySQL数据库