Spring Boot 分层架构详解:Controller、Service、Mapper...

在构建企业级后端应用时,良好的分层架构 不仅能提升代码的可读性和可维护性,也能帮助团队实现职责清晰、功能复用的目标。本文将详细介绍

Spring Boot 项目中常见的分层结构,重点讲解 ControllerServiceMapper 各层的职责、使用方式与最佳实践。


📚 一、为什么要分层?

我们在开发 Spring Boot 项目时,并不是所有代码堆在一个类里,而是根据功能职责划分为不同的"层",以实现:

  • 职责清晰
  • 降低耦合
  • 易于测试
  • 易于扩展和维护

这就是典型的 MVC(Model-View-Controller)+ Service + DAO 架构。


🧱 二、Spring Boot 项目的典型分层结构

层级 英文名称 主要职责 是否写 SQL 是否处理业务 是否响应请求
表现层 Controller 接收前端 HTTP 请求、处理参数、调用业务逻辑、返回响应结果 ❌(只转发)
业务逻辑层 Service 封装业务逻辑、事务控制、调用数据访问接口、组织业务流程
数据访问层 Mapper / DAO 定义数据库操作,配合 XML 或注解执行 SQL
数据模型层 Entity / Model 封装数据库表结构对应的数据对象,进行前后端数据传输
配置层 Config 配置类,如数据源、拦截器、跨域处理、安全策略等
启动器层 Application 应用程序启动入口,加载配置并启动 Spring Boot 环境

📁 三、目录结构推荐

一个标准的 Spring Boot + MyBatis 项目结构如下:

复制代码
src/
 └── main/
     ├── java/com/example/demo/
     │   ├── controller/     // 接收请求
     │   ├── service/        // 编写业务逻辑
     │   ├── mapper/         // 与数据库交互
     │   ├── model/          // 数据对象(Entity)
     │   ├── config/         // 配置类
     │   └── DemoApplication.java
     └── resources/
         ├── mapper/         // MyBatis XML 文件
         └── application.yml // 配置文件

🧩 四、各层职责详解

✅ 1. Controller ------ 表现层

  • 接收 HTTP 请求(@GetMapping/@PostMapping
  • 处理请求参数(@RequestParam/@RequestBody
  • 调用 Service 进行业务处理
  • 返回响应结果(ResponseEntity/JSON

示例:

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User getById(@PathVariable Long id) {
        return userService.getUserById(id);
    }
}

✅ 2. Service ------ 业务逻辑层

  • 编写业务逻辑(如注册、下单、积分计算等)
  • 事务控制(使用 @Transactional
  • 调用多个 Mapper 或外部服务
  • 拆分复杂业务流程,提升可复用性

示例:

java 复制代码
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUserById(Long id) {
        return userMapper.selectById(id);
    }
}

✅ 3. Mapper ------ 数据访问层(DAO)

  • 编写 SQL 语句(使用 MyBatis 注解或 XML)
  • 与数据库进行交互(增删改查)
  • 不处理业务逻辑,仅作为数据库操作的封装器

示例(注解方式):

java 复制代码
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User selectById(Long id);
}

示例(XML 方式):

xml 复制代码
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="selectById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

✅ 4. Model ------ 数据模型层

  • 定义实体类,用于封装数据库字段
  • 一般对应数据库中的一张表
  • 用作 Controller 与 Service 之间传递的数据对象

示例:

java 复制代码
@Data
public class User {
    private Long id;
    private String username;
    private String email;
}

💡 五、常见疑问解答

❓1. Controller 可以代替 Service 吗?

从技术上讲:可以写在一起。

从架构上讲:绝对不推荐!

👉 原因:

  • Controller 是面向接口的,只管"接收"与"响应"
  • Service 专注处理业务,解耦逻辑,有利于测试、复用、事务控制

❓2. Controller 可以代替 Mapper 或 XML 吗?

完全不能。

  • Controller 不应该操作数据库;
  • Mapper/XML 专门用来写 SQL;
  • 控制层不应承担数据库逻辑。

✅ 六、总结

Controller 管接口,Service 管逻辑,Mapper 管数据库,Model 管数据结构。


相关推荐
豌豆花下猫3 分钟前
Python 潮流周刊#111:Django迎来 20 周年、OpenAI 前员工分享工作体验(摘要)
后端·python·ai
LaoZhangAI19 分钟前
ComfyUI集成GPT-Image-1完全指南:8步实现AI图像创作革命【2025最新】
前端·后端
LaoZhangAI20 分钟前
Cline + Gemini API 完整配置与使用指南【2025最新】
前端·后端
LaoZhangAI32 分钟前
Cline + Claude API 完全指南:2025年智能编程最佳实践
前端·后端
remCoding2 小时前
Java大厂面试实录:从Spring Boot到AI微服务架构的深度拷问
spring boot·spring cloud·kafka·java面试·jakarta ee·ai面试·ai微服务
IguoChan3 小时前
9. Redis Operator (2) —— Sentinel部署
后端
曾经的三心草3 小时前
微服务的编程测评系统2
微服务·云原生·架构
ansurfen3 小时前
耗时一周,我的编程语言 Hulo 新增 Bash 转译和包管理工具
后端·编程语言
库森学长3 小时前
索引失效的场景有哪些?
后端·mysql·面试