小白怎么理解后端分层概念

我们来用一个通俗的比喻帮你理解后端分层:把整个后端应用想象成一家餐厅

  • 控制层(Controller) -- 餐厅的服务员
    负责接待客人(前端请求),记录客人要点什么菜(参数),然后把菜单交给后厨,最后把做好的菜端给客人(返回响应)。
  • 服务层(Service) -- 厨师
    负责具体的做菜流程(业务逻辑),比如这道菜需要哪些食材、烹饪顺序、加什么调料。厨师不会自己去买菜,而是通知采购员。
  • 数据访问层(Repository/DAO) -- 采购员
    负责去仓库(数据库)取食材、存储食材、更新食材。它只关心怎么和数据库打交道,不关心菜怎么做。
  • 模型/实体层(Model/Entity) -- 菜单/菜品
    定义了每道菜的组成(数据结构),比如菜名、价格、口味等。它贯穿各层,让数据在不同的角色之间传递时保持格式统一。

1. 各层详细说明

控制层(Controller)

  • 作用:接收 HTTP 请求,解析参数,调用 Service 层的方法,并将 Service 返回的结果封装成 HTTP 响应。
  • 典型注解@RestController@RequestMapping
  • 职责 :参数校验、响应格式转换、路由映射。不包含业务逻辑

服务层(Service)

  • 作用:实现核心业务逻辑。比如计算订单总价、检查库存、调用多个 Repository 完成一个复杂事务。
  • 典型注解@Service
  • 职责 :处理事务(@Transactional),调用数据访问层,组装业务对象。不直接处理 HTTP 细节

数据访问层(Repository / DAO)

  • 作用:封装对数据库的 CRUD 操作。通过 JPA、MyBatis 等技术将对象映射到数据库表。
  • 典型注解@Repository
  • 职责 :执行 SQL、查询结果、持久化数据。不包含业务逻辑

模型层(Model / Entity / DTO)

  • Entity :与数据库表一一对应的 Java 对象,通常放在 entity 包。
  • DTO(Data Transfer Object):在层之间传输数据的对象,比如 Controller 返回给前端的结构,常与 Entity 分开避免暴露数据库字段。
  • VO(View Object):专门用于前端展示的对象,与 DTO 类似但更偏视图层。

辅助角色:Maven 与 Spring Boot

  • Maven:项目构建工具。帮你管理 jar 包依赖(如 Spring、数据库驱动),并负责编译、打包成可运行的 jar/war。
  • Spring Boot:基于 Spring 的快速开发框架。它内置了 Tomcat 服务器,通过"自动配置"让你不用手动配置大量 XML,只需少量注解就能跑起一个项目。

2. 数据流转与关系图

下面是一个典型的请求处理流程,用 Mermaid 流程图 展示。

(如果你在支持 Mermaid 的编辑器中查看,可以直接渲染;不支持时也可以看下方的文字描述)
前端发送 HTTP 请求
控制层 Controller
调用 Service 层
服务层 Service
调用 Repository 层
数据访问层 Repository
数据库
返回 HTTP 响应给前端

文字流程说明

  1. 前端(浏览器/App)发起 HTTP 请求(如 POST /api/order)。
  2. 请求被 Controller 拦截,根据 URL 路由到对应的方法。
  3. Controller 解析请求参数,调用 Service 层的某个方法。
  4. Service 层执行业务逻辑:可能调用多个 Repository 方法,并利用 Entity 对象传递数据。
  5. Repository 使用 JPA 或 MyBatis 将操作翻译成 SQL,与数据库交互。
  6. 数据库返回结果,Repository 将结果封装成 Entity 对象返回给 Service。
  7. Service 处理完毕后,可能将 Entity 转换为 DTO 返回给 Controller。
  8. Controller 将 DTO 封装成 JSON 格式的 HTTP 响应,返回给前端。

3. 为什么这样分层?

  • 解耦:每一层只关心自己的职责,修改数据库实现不影响业务层,修改业务逻辑不影响接口。
  • 可测试:可以对 Service 层单独做单元测试,Mock Repository 即可,无需启动数据库和 Web 服务器。
  • 维护性:代码结构清晰,新人能快速定位到某段逻辑的位置。
  • 复用性:Service 可以被多个 Controller 复用,Repository 可以被多个 Service 复用。

4. 代码示例(Spring Boot 风格)

Entity(实体)

java 复制代码
@Entity
public class Order {
    @Id
    private Long id;
    private String product;
    private Integer quantity;
    // getter/setter...
}

Repository

java 复制代码
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    List<Order> findByProduct(String product);
}

Service

java 复制代码
@Service
@Transactional
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;

    public Order createOrder(OrderDto dto) {
        // 业务逻辑:比如检查库存
        Order order = new Order();
        order.setProduct(dto.getProduct());
        order.setQuantity(dto.getQuantity());
        return orderRepository.save(order);
    }
}

Controller

java 复制代码
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @PostMapping
    public ResponseEntity<Order> create(@RequestBody OrderDto dto) {
        Order order = orderService.createOrder(dto);
        return ResponseEntity.ok(order);
    }
}

5. 常见问题

  • Controller 能不能直接调用 Repository?

    可以,但不推荐。因为业务逻辑会散落在 Controller 中,一旦需要被另一个接口复用,就会造成重复代码。Service 层专门收容业务逻辑。

  • DTO 和 Entity 什么时候用?

    一般 Entity 用于数据库映射,DTO 用于对外传输(避免暴露数据库字段,或组合多个 Entity 的数据)。Controller 接收前端参数时常用 DTO,返回给前端时也常用 DTO。

  • Maven 在这里起什么作用?

    Maven 通过 pom.xml 声明项目依赖(比如 spring-boot-starter-web、spring-boot-starter-data-jpa),它会自动下载这些 jar 包并加入 classpath。你只需要写代码,打包时用 mvn package 就能生成可运行的 jar。


相关推荐
stark张宇2 小时前
Golang后端面试复盘:从Swoole到IM架构,如何支撑360w用户的实时消息推送?
后端
小码哥_常2 小时前
从0到1:搭建Spring Boot 3企业级认证授权平台
后端
小码哥_常2 小时前
告别扫库噩梦!Spring Boot+Redis让订单超时管理飞起来
后端
大傻^3 小时前
Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建
java·人工智能·后端·spring·springai·springaialibaba
IT_陈寒4 小时前
SpringBoot实战:3个隐藏技巧让你的应用性能飙升50%
前端·人工智能·后端
彭于晏Yan4 小时前
MQTT消息服务
spring boot·后端·中间件
程序员Sunday4 小时前
Claude Code 生态爆发:5个必知的新工具
前端·人工智能·后端
weixin_387534225 小时前
Ownership - Rust Hardcore Head to Toe
开发语言·后端·算法·rust
前端付豪5 小时前
实现一个用户可以有多个会话
前端·后端·llm