SpringBoot 整合 MyBatis 读取 MySQL 数据——完整开发实录

本文记录 L06 作业的完整开发过程:用 SpringBoot + MyBatis-Plus 读取 MySQL 数据,实现用户管理的 5 个 REST 接口,并用 Postman 完成全部测试。

一、需求与整体思路

前端浏览器发起 HTTP 请求,后端 SpringBoot 程序响应;而数据需要永久保存(程序 crash 后仍在)、支持大量数据存储与高效访问,因此引入 MySQL。MyBatis 负责把 SQL 查询结果转成 Java 对象,供 SpringBoot 程序使用。

整体采用业界约定的四层结构,访问顺序自上而下:Controller(暴露 REST 接口)→ Service(业务逻辑)→ Mapper(数据访问接口)→ Mapper XML(转化为 SQL)→ MySQL 数据库;domain 包下的 User 类作为表数据对应的 Java 实体。

二、MySQL 数据库准备(Navicat)

在 Navicat 中创建数据库 mybatis,新建 user 表,包含 5 个字段:

字段 类型 说明
id int 主键、自增、无符号、非空
name varchar(50) 用户名
birthday date 生日
sex varchar(1) 性别
create_time datetime 创建时间

表设计界面如下,注意 id 要设为主键并勾选"自动递增"和"无符号":

再插入 10 条模拟数据,作为接口测试的数据基础:

三、项目配置:pom 依赖与 application.yml

项目基于 Spring Boot 4.1.1 + Java 21(Maven)。pom.xml 中加入 MyBatis-Plus 的 Boot4 专用 starter(Boot 4.x 必须用 spring-boot4 版本,不能与 boot3 版混用)和 MySQL 驱动:

xml 复制代码
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
    <version>3.5.16</version>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

在 src/main/resources 目录下创建 application.yml,配置项目端口、数据源以及 MyBatis-Plus 参数(log-impl 让 SQL 打印到控制台方便调试;id-type: auto 对应数据库自增;逻辑删除配置预留):

yaml 复制代码
server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: ******

application.yml 配置界面:

四、代码实现(controller / service / mapper / domain 四层)

按业界约定的目录结构新建四个包,并在 resources 下新建 mapper 资源目录(存放 XML 映射文件):

1. domain 实体类 User:@TableName 对应表名(user 是 MySQL 保留字,要加反引号),@TableId(type = IdType.AUTO) 对应自增主键,lombok @Data 自动生成 getter/setter:

java 复制代码
@Data
@TableName("`user`")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @TableId(type = IdType.AUTO)
    private Integer id;
    private String name;
    private LocalDate birthday;
    private String sex;
    private LocalDateTime createTime;
}

2. mapper 层:UserMapper 接口继承 BaseMapper<User> 即可获得单表 CRUD 能力;启动类上加 @MapperScan("com.example.l06_cp.mapper") 批量扫描(注意 import 的是 org.mybatis.spring.annotation.MapperScan,不是 ibatis 包)。

3. service 层:UserService 接口继承 IService<User>;实现类 UserServiceImpl 继承 ServiceImpl<UserMapper, User> 并实现 UserService,加 @Service 注解交给 Spring 管理。

4. controller 层:统一返回 Result<T> 通用结构(code/message/data),通过 @Autowired 注入 UserService,向外提供 5 个 REST 接口。Controller 整体代码:

五、Postman 接口测试

启动项目后,用 Postman 对 5 个接口逐一测试,全部通过(统一返回 code=200):

1. 根据用户 id 获取用户信息 GET /api/user/{id},成功查到 id=1 的数据:

2. 获取所有用户信息 GET /api/user/list,返回 10 条模拟数据:

3. 添加用户信息 POST /api/user,Body 传 JSON,新增"陈鹏"成功(id 自动递增分配):

4. 更新某个用户信息 PUT /api/user,根据 id 把用户名改为"张三":

5. 删除某个用户信息 DELETE /api/user/{id},删除测试数据成功:

六、自定义 SQL:@Select 注解 与 mapper.xml 两种方式

方式一:@Select 注解直写 SQL(适合简单语句)。在 UserMapper 中添加 getAllUserSortByNameDesc 方法:

java 复制代码
@Select("SELECT * FROM `user` ORDER BY name DESC")
List<User> getAllUserSortByNameDesc();

Service 层通过 baseMapper 调用,Controller 新增接口暴露。

Postman 测试------按名字倒序返回:

方式二:与 mapper.xml 配合(适合复杂 SQL)。在 resources/mapper 下新建 UserMapper.xml:namespace 对应 Mapper 接口全限定名,<select id> 对应接口方法名:

xml 复制代码
<mapper namespace="com.example.l06_cp.mapper.UserMapper">
    <select id="selectUserList" resultType="com.example.l06_cp.domain.User">
        SELECT * FROM `user`
    </select>
</mapper>

Postman 测试 selectUserList 接口:

七、踩坑记录

  1. 启动报 Access denied for 'root'@'localhost':application.yml 里的密码是教程的假设值,改成自己 MySQL 的真实密码即可;
  2. @MapperScan 导错包:它不在 org.apache.ibatis.annotations 里(那里只有 @Mapper),正确的是 org.mybatis.spring.annotation.MapperScan,来自 mybatis-spring 整合包;
  3. POST/PUT 传时间字段报 400:Jackson 默认只认 ISO 格式,LocalDateTime 传参要写成 2026-01-05T09:15:00(日期时间是字母 T 分隔),或在实体字段上加 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss");
  4. 自增 id 出现空洞:删除过的记录编号不会被复用,AUTO_INCREMENT 只进不退,属正常现象,判断条数要用 COUNT(*) 而不是 max(id);
  5. 8080 端口被占用:上次启动的 Java 进程没退干净,用 netstat -ano | findstr :8080 找到 PID,taskkill /F /PID xxx 结束即可。

八、总结

本项目完整走通了 SpringBoot + MyBatis-Plus 读写 MySQL 的最小闭环:Navicat 建库建表 → application.yml 配置数据源 → domain / mapper / service / controller 四层代码 → Postman 全接口测试,并分别用 @Select 注解和 mapper.xml 两种方式实现自定义 SQL。最大的收获是理解了四层结构各自的职责边界,以及"有业务逻辑才在 Service 层建方法,纯透传直接调 IService 内置方法"的取舍。

相关推荐
小卿噢1 小时前
50 万个定时器,四种实现差了 115 倍
后端
用户54817845909501 小时前
CDN 实战:如何用 4 步让网站提速 10 倍
后端
MaxHua1 小时前
达梦 DTS 迁移 MySQL 报错 - 3236:此列列表已索引 解决方案
数据库·后端
琳达爱分享1 小时前
从单机令牌桶到集群限流:一次配额超发的复盘
后端·算法
leo在掘金1 小时前
亚马逊开源TorchNeuron:改1行代码跑上Trainium
后端·架构
青岛中阳消防1 小时前
分布式光纤火灾探测器安装常见问题、光缆敷设与光纤熔接解析
后端
弈栈录1 小时前
向量化、召回与重排序服务的实现
后端·面试·架构
智驭未来掌门人1 小时前
雷达架构梳理:那些容易混淆的边界与分层
后端