告别混乱!Spring Boot + MyBatis 标准化开发:结构解析 + 接口实战 + Checklist
项目结构是代码的 “骨架”,清晰的目录划分能让每个文件 “各归其位”。以下是完整的项目目录树,标注了核心文件的作用:
一、先懂结构:Maven 标准项目目录(Spring Boot + MyBatis)
Controller → Service → Mapper → DB
Spring Boot + MyBatis 项目结构(Maven标准)项目根目录
├── pom.xml # Maven 项目配置文件,依赖、插件、构建等
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── xxx
│ │ │ └── fullMarketing
│ │ │ ├── controller/api/web # 控制层 (Web 接口入口) 1. 接收HTTP请求;2. 参数校验(接收 DTO);3. 调用 Service 层方法;4. 封装结果返回给前端
│ │ │ │ ├── TopicController.java
│ │ │ │ └── ...
│ │ │ ├── service # 业务逻辑层(接口+实现类)1. 处理业务逻辑;2. 做必要的校验、事务控制;3. 调用 Mapper 层访问数据库
│ │ │ │ ├── TopicService.java
│ │ │ │ ├── impl
│ │ │ │ │ └── TopicServiceImpl.java
│ │ │ │ └── ...
│ │ │ ├── mapper # DAO层(MyBatis Mapper数据访问接口)1. 定义数据库操作方法
│ │ │ │ ├── TopicMapper.java
│ │ │ │ └── ...
│ │ │ ├── model # 数据库映射实体类(Entity/POJO)1. 映射 DB 表结构到Java类
│ │ │ │ ├── MarketingContentTopic.java
│ │ │ │ └── ...
│ │ │ ├── dto # 数据传输/返回对象(请求/响应结构)
│ │ │ │ ├── TopicOfflineRequest.java
│ │ │ │ └── ...
│ │ │ ├── vo # 视图对象(返回给前端的格式)
│ │ │ │ └── ...
│ │ │ ├── config # 项目配置类(Swagger, MyBatis, Security等)
│ │ │ ├── util # 工具类(时间处理,字符串处理等)
│ │ │ └── FullMarketingApplication.java # Spring Boot 启动入口
│ │ ├── resources
│ │ │ ├── application.yml # 项目主配置文件
│ │ │ ├── static # 静态资源文件夹(图片/CSS/JS)
│ │ │ ├── templates # HTML模板文件(Thymeleaf/Freemarker等)
│ │ │ ├── mapper # MyBatis XML SQL文件目录
│ │ │ │ ├── TopicMapper.xml # 对应 Mapper 接口
│ │ │ │ └── ...
│ │ │ ├── logback-spring.xml # 日志配置
│ │ │ └── banner.txt # 启动Banner
│ │ └── webapp # (可选)存放 web 相关资源
│ └── test # 测试代码
│ ├── java
│ │ └── com
│ │ └── xxx
│ │ └── fullMarketing
│ │ └── TopicServiceTest.java # 单元测试类
│ └── resources # 测试时需要的资源文件
└── target # Maven 构建输出目录(编译后class/jar包)
二、再明职责:各模块核心作用对照表
很多新手会混淆DTO和VO、Model和Mapper,下表清晰列出每个模块的 “职责边界”,避免开发时 “放错文件”:
| 文件夹路径 | 作用 | 关键注意点 |
|---|---|---|
controller | 控制层:接收 HTTP 请求并调用 Service 层,返回结果给前端 | 不处理业务逻辑!仅负责请求接收、参数初步校验和结果封装,避免与业务层耦合 |
service | 业务逻辑层:处理业务规则、事务控制等 | 业务逻辑集中在此,通过接口 + 实现类分离降低耦合,@Transactional 注解需指定 rollbackFor 确保异常回滚 |
mapper | 数据访问层(DAO):定义对数据库的操作接口,MyBatis 实现 | 仅定义方法签名,SQL 语句统一放在 resources/mapper 目录的 XML 文件中,自定义方法需用 @Param 指定参数名 |
model | 数据库实体类:映射数据表,与 MyBatis-Plus 配合使用 | 字段名、数据类型需与数据库表完全对应,可通过 @TableName、@TableId 等注解解决命名不一致问题 |
dto | 请求/响应对象:封装接口的入参和出参 | 避免直接暴露数据库实体类,通过 @NotBlank、@NotNull 等注解实现参数校验,不同接口单独定义 DTO 保证灵活性 |
vo | 视图对象:返回给前端的专用结构 | 避免直接暴露数据库实体类,通过 @NotBlank、@NotNull 等注解实现参数校验,不同接口单独定义 DTO 保证灵活性 |
config | 项目配置类(Swagger、MyBatis、Security、跨域配置等) | 用 @Configuration 注解标识配置类,替代传统 XML 配置,配置类需按功能分类(如 SwaggerConfig、CorsConfig) |
util | 工具类,比如时间处理、字符串工具等 | 用 @Configuration 注解标识配置类,替代传统 XML 配置,配置类需按功能分类(如 SwaggerConfig、CorsConfig) |
resources/mapper | 存放 MyBatis XML 文件,与 Java Mapper 接口对应 | 用 @Configuration 注解标识配置类,替代传统 XML 配置,配置类需按功能分类(如 SwaggerConfig、CorsConfig) |
resources/static | 静态资源(前端JS、CSS、图片) | 适合前后端不分离项目,前后端分离项目建议前端单独部署,此目录可留空或用于存放少量公共静态资源 |
resources/templates | 页面模板(Thymeleaf、Freemarker) | 仅用于前后端不分离项目,模板文件需放在指定目录,通过 Controller 的 String 返回值指定模板路径 |
test/java | 单元测试代码 | 仅用于前后端不分离项目,模板文件需放在指定目录,通过 Controller 的 String 返回值指定模板路径 |
target | Maven 编译输出目录,打包 jar/war | 仅用于前后端不分离项目,模板文件需放在指定目录,通过 Controller 的 String 返回值指定模板路径 |
DTO 作用:
- 隔离:避免直接把数据库实体类(Entity)暴露给接口。
- 设计清晰:不同接口用不同的请求/响应类,方便维护和扩展。
- 参数验证:可以在字段上加校验注解,直接在 Controller 层拦截非法请求。
三、实战流程:从 0 到 1 开发 “下线话题” 接口
以“下线话题”(前端传入话题 ID,后端更新话题状态为 “下线”)为例,走一遍标准化开发流程。
| 步骤 | 操作内容 | 目标文件夹 | 示例文件 | 备注 |
|---|---|---|---|---|
| 1 | 确定接口需求(输入参数、处理逻辑、输出结果) | —— | —— | 写在需求文档或任务卡里 |
| 2 | 创建/修改 DTO(请求对象) | src/main/java/com/xxx/fullMarketing/dto | TopicOfflineRequest.java | 如果请求包含参数,就需要 DTO;加校验注解 |
| 3 | 创建 Controller 方法 | src/main/java/com/xxx/fullMarketing/controller | TopicController.java | 用 @RestController 或 @Controller,加路由 @PostMapping("/offline") |
| 4 | 在 Controller 方法中调用 Service | 同上 | TopicController.java | 参数加 @Valid 校验,调用 topicService.xxx(...) |
| 5 | 在 Service 接口添加方法声明 | src/main/java/com/xxx/fullMarketing/service | TopicService.java | 声明 void offlineTopic(String topicId) |
| 6 | 在 Service 实现类里编写逻辑 | src/main/java/com/xxx/fullMarketing/service/impl | TopicServiceImpl.java | 处理业务逻辑(调用 Mapper 更新数据库) |
| 7 | 在 Mapper 接口添加方法声明 | src/main/java/com/xxx/fullMarketing/mapper | TopicMapper.java | 用 @Param 指定参数名 |
| 8 | 在 MyBatis XML 添加 SQL | src/main/resources/mapper | TopicMapper.xml | 用 <update> / <select> 根据需求写 SQL |
| 9 | 检查 Entity 是否映射正确 | src/main/java/com/xxx/fullMarketing/model | MarketingContentTopic.java | 确保字段与表对应,类型一致 |
| 10 | 测试接口(单元测试 / Postman) | src/test/java/com/xxx/fullMarketing | TopicServiceTest.java | 确认逻辑正确、SQL执行正常、返回符合预期 |
| 11 | 更新文档(Swagger自动生成或手动) | src/main/java/com/xxx/fullMarketing/controller | 同 Controller | 使用 @Schema 等注解保证 API 文档可读性 |
| 12 | 提交代码并 PR | —— | —— | 按项目的代码提交流程提交 |
四、可视化链路:接口开发全链路流程图
为了更直观理解 “下线话题” 接口的请求流转逻辑,以下是从前端发起请求到数据库返回结果的完整流程图,清晰标注各环节对应的代码文件和核心操作:
┌───────────────┐
│ 前端 / Postman │ # 发起HTTP请求(POST /api/web/topic/offline,携带JSON参数)
└───────┬───────┘↓
┌───────────────┐ # 1. 接收请求+参数校验
│ controller/ │
│ TopicController.java │
│ - @PostMapping路由匹配 │
│ - @Valid校验TopicOfflineRequest │ # 触发DTO参数校验(非空、格式等)
└───────┬───────┘↓ # 校验通过后,调用Service层方法
┌───────────────┐ # 2. 业务逻辑处理
│ service/ │
│ TopicService.java(接口) │ # 声明offlineTopic(String topicId)方法
└───────┬───────┘↓
┌───────────────┐
│ service/impl/ │ # 实现业务逻辑(校验话题状态、事务控制)
│ TopicServiceImpl.java │
│ - @Transactional保证事务原子性 │
│ - 校验话题是否存在/已下线 │
│ - 调用Mapper更新数据库 │
└───────┬───────┘↓ # 调用数据访问层方法
┌───────────────┐ # 3. 定义数据库操作接口
│ mapper/ │
│ TopicMapper.java │ # 继承BaseMapper,使用updateById方法(或自定义方法)
└───────┬───────┘↓ # 执行SQL语句
┌───────────────┐ # 4. SQL语句执行
│ resources/ │
│ mapper/TopicMapper.xml │ # 若自定义方法,此处编写<update>SQL(例:更新status=0)
└───────┬───────┘↓ # 操作数据库表
┌───────────────┐ # 5. 数据库交互
│ 数据库 │
│ marketing_content_topic │ # 更新指定topicId的status字段为“下线”(0)
└───────┬───────┘↓ # 返回执行结果(成功/失败)
┌───────────────┐ # 6. 结果封装返回
│ controller/ │
│ TopicController.java │ # 接收Service返回结果,封装为ResultDTO(含success/msg)
└───────┬───────┘↓
┌───────────────┐ # 7. 前端接收响应
│ 前端 / Postman │ # 展示结果(如:{"success":true,"msg":"话题下线成功"})
└───────────────┘
注意事项
- 两层校验:拦截异常
说明:Controller 层 DTO 校验(防空参数),Service 层业务校验(防重复下线);
注意:必选参数加@NotNull/@NotBlank,提示语要明确(如 “话题 ID 不能为空”)。 - 事务控制:防数据不一致
说明:Service 层用@Transactional保证 “校验→更新” 原子性,失败回滚;
注意:多数据库操作必加,指定rollbackFor=Exception.class,非 DB 操作别进事务。 - MyBatis 交互:选对方式
说明:简单 CRUD 用 BaseMapper(免 XML),复杂操作写 XML 动态 SQL;
注意:XML 更新 / 删除必查WHERE条件(防全表操作),Model 字段要和表对应。 - 结果流转:统一格式
说明:Controller 层统一封装 ResultDTO(success+msg+data),前后端交互一致;
注意:全链路参数类型要匹配(如 Long/String 别混),响应提示别模糊(如不说 “操作失败”)。
新接口开发 Checklist
- [ ] 确定接口需求(输入/输出/逻辑)
- [ ] 创建/修改 DTO(请求对象)
- [ ] 创建 Controller 方法并调用 Service
- [ ] 添加 Service 接口方法
- [ ] 在 Service 实现类中编写逻辑
- [ ] 添加 Mapper 接口方法声明
- [ ] 在 MyBatis XML 中添加 SQL
- [ ] 检查 Entity 字段映射
- [ ] 测试接口(单元测试 / 集成测试 / Postman)
- [ ] 更新接口文档
- [ ] 提交代码并发起 PR
