Java/后端
Spring Boot + MyBatis-Plus 项目结构与配置整理
本文整理了一个标准 Spring Boot + MyBatis-Plus 项目的核心文件结构,包括配置文件、实体类、Mapper 接口、启动类、配置类和测试类。适合作为搭建项目时的速查手册。
本文整理了一个标准 Spring Boot + MyBatis-Plus 项目的核心文件结构,包括配置文件、实体类、Mapper 接口、启动类、配置类和测试类。适合作为搭建项目时的速查手册。
一、项目结构总览
src/main/java/com/example/demo/
├── DemoApplication.java ← 启动类
├── config/
│ └── MyBatisPlusConfig.java ← MyBatis-Plus 配置类
├── entity/
│ └── User.java ← 实体类
├── mapper/
│ └── UserMapper.java ← Mapper 接口
└── ...
src/main/resources/
└── application.yaml ← 配置文件
src/test/java/com/example/demo/
└── DemoApplicationTests.java ← 测试类
二、application.yaml —— 核心配置文件
server:
servlet:
context-path: /dev-api
port: 8080
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/20260614-demo?characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
说明
| 配置项 | 作用 |
|---|---|
server.port | 服务端口,默认 8080 |
server.servlet.context-path | 全局路径前缀,所有接口前面都会带上 /dev-api |
spring.datasource.url | 数据库连接地址 |
spring.datasource.username | 数据库用户名 |
spring.datasource.password | 数据库密码 |
spring.datasource.driver-class-name | MySQL 驱动类 |
URL 参数解释
characterEncoding=UTF-8:字符编码,防止中文乱码。serverTimezone=UTC:时区设置,避免时间相差 8 小时。
注意事项
- YAML 缩进必须用空格,不能用 Tab。
- 冒号后面必须有空格。
driver-class-name对 MySQL 8+ 用com.mysql.cj.jdbc.Driver,5.x 用com.mysql.jdbc.Driver。
三、User.java —— 实体类
package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("`user`")
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
注解说明
| 注解 | 作用 |
|---|---|
@Data | Lombok 注解,自动生成 getter、setter、toString、equals、hashCode |
@TableName("user") | MyBatis-Plus 注解,指定这个类对应数据库中的 user 表 |
为什么表名要加反引号
user 是 MySQL 的关键字(表示当前用户),直接用会报语法错误。用反引号 `user` 包裹,告诉 MySQL 这是一个表名而不是关键字。
字段与列的对应
默认情况下,MyBatis-Plus 会把驼峰命名的字段自动映射为下划线命名的列:
| 字段 | 对应列 |
|---|---|
id | id |
name | name |
age | age |
email | email |
如果字段名和列名不一致(比如 userName 对应 user_name),可以加 @TableField("user_name") 手动指定。
四、UserMapper.java —— Mapper 接口
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
说明
| 部分 | 作用 |
|---|---|
@Mapper | 标记这是一个 MyBatis Mapper 接口,Spring 会为它生成动态代理对象 |
extends BaseMapper<User> | 继承 MyBatis-Plus 的基础 Mapper,自动获得 CRUD 方法 |
BaseMapper 自带的方法
继承 BaseMapper<User> 后,不需要写任何 SQL,就自动拥有以下方法:
| 方法 | 作用 |
|---|---|
insert(User user) | 新增 |
deleteById(Long id) | 根据 ID 删除 |
updateById(User user) | 根据 ID 更新 |
selectById(Long id) | 根据 ID 查询 |
selectList(Wrapper) | 条件查询列表 |
selectPage(Page, Wrapper) | 分页查询 |
这就是 MyBatis-Plus 的核心价值:单表 CRUD 不用写 SQL。
@Mapper 和 @MapperScan 的关系
- 如果用
@MapperScan指定了包路径,接口上可以不写@Mapper。 - 如果没用
@MapperScan,每个 Mapper 接口都必须写@Mapper。 - 两者选一个即可,不要重复。
五、MyBatisPlusConfig.java —— 配置类
package com.example.demo.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
@MapperScan("com.example.demo.mapper")
@Configuration
public class MyBatisPlusConfig {
}
注解说明
| 注解 | 作用 |
|---|---|
@Configuration | 标记这是一个配置类,Spring 启动时会加载它 |
@MapperScan("com.example.demo.mapper") | 批量扫描指定包下的 Mapper 接口,自动注册为 Spring Bean |
为什么要单独建一个配置类
- 启动类上只保留
@SpringBootApplication,职责单一。 - 所有配置相关的代码集中到
config包下,结构清晰。 - 以后要加 MyBatis-Plus 的分页插件、乐观锁插件等,也在这个类里配置。
分页插件示例(进阶)
@Configuration
@MapperScan("com.example.demo.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
加上这个插件后,selectPage 才能真正实现分页。
六、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);
}
}
说明
| 部分 | 作用 |
|---|---|
@SpringBootApplication | 组合注解,包含 @Configuration、@EnableAutoConfiguration、@ComponentScan |
SpringApplication.run(...) | 启动 Spring Boot 应用,加载所有 Bean |
@SpringBootApplication 拆解
它等价于以下三个注解的组合:
| 注解 | 作用 |
|---|---|
@Configuration | 标记这是一个配置类 |
@EnableAutoConfiguration | 开启自动配置,Spring Boot 的核心 |
@ComponentScan | 扫描当前包及子包下的所有组件 |
所以启动类必须放在项目根包下,否则扫描不到子包里的 Controller、Service、Mapper。
七、DemoApplicationTests.java —— 测试类
package com.example.demo;
import com.example.demo.mapper.UserMapper;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Resource
private UserMapper userMapper;
@Test
void TestContent() {
}
}
注解说明
| 注解 | 作用 |
|---|---|
@SpringBootTest | 启动完整的 Spring 容器,用于集成测试 |
@Resource | 依赖注入,把 Spring 容器里的 UserMapper 注入进来 |
@Test | JUnit 5 注解,标记这是一个测试方法 |
@Resource vs @Autowired
| 注解 | 来源 | 注入策略 |
|---|---|---|
@Resource | JDK 标准(jakarta.annotation) | 默认按名字注入 |
@Autowired | Spring 提供 | 默认按类型注入 |
两者都可以用,Spring Boot 3 时代推荐 @Resource 或构造器注入。
测试类的作用
写完 Mapper 后,不启动整个 Web 服务,就能直接测试数据库操作:
@SpringBootTest
class DemoApplicationTests {
@Resource
private UserMapper userMapper;
@Test
void testSelect() {
User user = userMapper.selectById(1L);
System.out.println(user);
}
}
点击方法左侧的绿色三角运行,如果能打印出数据,说明数据库连接、实体映射、Mapper 代理全部正常。
八、完整调用链路
一个请求从前端到数据库,经过以下链路:
浏览器 / Postman
↓
Controller(接收请求,调用 Service)
↓
Service(业务逻辑,调用 Mapper)
↓
Mapper(MyBatis-Plus 动态代理,生成 SQL)
↓
DataSource(连接池,管理数据库连接)
↓
MySQL(执行 SQL,返回结果)
各层职责
| 层 | 职责 | 注解 |
|---|---|---|
| Controller | 接收 HTTP 请求,返回 JSON | @RestController、@GetMapping 等 |
| Service | 业务逻辑,事务控制 | @Service |
| Mapper | 数据库访问 | @Mapper 或 @MapperScan |
| Entity | 数据载体,对应数据库表 | @TableName、@Data |
九、常见问题排查
1. 启动报错“找不到 Mapper”
- 检查
@MapperScan的包路径是否写对。 - 检查启动类是否在根包下(能扫描到子包)。
2. 数据库连不上
- 检查
application.yaml里的 URL、用户名、密码。 - 检查 MySQL 服务是否启动。
- 检查数据库是否已创建。
3. 表名报错“语法错误”
- 如果表名是 MySQL 关键字(如
user、order),必须加反引号。
4. 字段映射不上
- 检查字段名和列名是否符合驼峰转下划线规则。
- 不一致时用
@TableField("列名")手动指定。
5. 测试类注入 Mapper 为 null
- 检查是否加了
@SpringBootTest。 - 检查 Mapper 是否被
@MapperScan扫描到。
十、总结
一个标准的 Spring Boot + MyBatis-Plus 项目,核心就是这几个文件:
| 文件 | 职责 |
|---|---|
application.yaml | 配置端口、数据库连接 |
DemoApplication.java | 启动类,入口 |
MyBatisPlusConfig.java | 配置类,扫描 Mapper |
User.java | 实体类,对应数据库表 |
UserMapper.java | Mapper 接口,继承 BaseMapper |
DemoApplicationTests.java | 测试类,验证数据库操作 |
掌握这套结构后,写任何单表 CRUD 都是模板套用,效率极高。MyBatis-Plus 帮你省掉了 90% 的 SQL 编写,让你专注于业务逻辑。