Spring Boot 分层架构与数据流转详解

核心分层架构图解析

具体来说👇

++························································形象来说👇++

++++

各层详细说明
  1. Controller(控制层)

    • 职责:接收HTTP请求,返回HTTP响应

    • 工作流程

      • 接收前端发送的请求数据(JSON/表单)

      • 调用Service处理业务逻辑

      • 将Service返回的VO对象转为JSON响应

    • 关键注解

      • @RestController:标记为控制器

      • @PostMapping/@GetMapping:定义API路径

      • @RequestBody:接收JSON请求体

      • @Valid:参数校验

  2. Service(服务层)

    • 职责:处理核心业务逻辑

    • 工作流程

      • 接收Controller传递的DTO对象

      • 调用Mapper操作数据库

      • 处理业务规则和计算

      • 将Entity转换为VO返回给Controller

    • 关键注解

      • @Service:标记为服务组件

      • @Transactional:管理数据库事务

  3. Mapper(数据访问层)

    • 职责:与数据库直接交互

    • 工作流程

      • 接收Service传递的Entity对象

      • 执行SQL语句(增删改查)

      • 将数据库结果转为Entity返回

    • 关键技术

      • MyBatis:SQL映射框架

      • @Mapper:标记Mapper接口

      • XML文件:编写SQL语句

  4. Entity(实体层)

    • 职责:映射数据库表结构

    • 特点

      • 与数据库表一一对应

      • 包含所有表字段

      • 不应包含业务逻辑

    • 示例

      java 复制代码
      @Data
      public class User {
          private Long id;
          private String username;
          private String password; // 敏感字段
          private Date createTime;
      }
  5. DTO(数据传输对象)

    • 职责:层间数据传输

    • 特点

      • 用于Controller接收请求数据

      • 只包含前端需要的字段

      • 包含数据校验规则

    • 示例

      java 复制代码
      public class UserDTO {
          @NotBlank
          private String username;
          
          @Size(min=6, max=20)
          private String password;
      }
  6. VO(视图对象)

    • 职责:返回给前端的数据

    • 特点

      • 只包含前端需要的数据

      • 对敏感字段脱敏

      • 格式化数据展示

    • 示例

      java 复制代码
      public class UserVO {
          private Long id;
          private String username;
          private String createTime; // 格式化后的字符串
      }
完整数据流转过程
  1. 前端发起请求

    • 发送HTTP请求(如POST /users)

    • 携带JSON数据(DTO格式)

  2. Controller接收请求

    java 复制代码
    @PostMapping("/users")
    public UserVO createUser(@Valid @RequestBody UserDTO userDTO) {
        return userService.createUser(userDTO);
    }
  3. Service处理业务

    java 复制代码
    @Service
    public class UserService {
        public UserVO createUser(UserDTO userDTO) {
            // DTO转Entity
            User user = new User();
            user.setUsername(userDTO.getUsername());
            user.setPassword(encodePassword(userDTO.getPassword()));
            
            // 保存到数据库
            userMapper.insert(user);
            
            // Entity转VO
            return convertToVO(user);
        }
    }
  4. Mapper操作数据库

    XML 复制代码
    <!-- UserMapper.xml -->
    <insert id="insert">
        INSERT INTO users (username, password) 
        VALUES (#{username}, #{password})
    </insert>
  5. VO返回给前端

    java 复制代码
    private UserVO convertToVO(User user) {
        UserVO vo = new UserVO();
        vo.setId(user.getId());
        vo.setUsername(user.getUsername());
        
        // 格式化日期
        vo.setCreateTime(formatDate(user.getCreateTime()));
        
        // 不返回密码等敏感字段
        return vo;
    }
为什么需要VO?
  1. 安全性:隐藏敏感字段(密码、内部ID等)

    java 复制代码
    // Entity包含敏感字段
    public class User {
        private String password;
        private String internalCode;
    }
    
    // VO只返回安全字段
    public class UserVO {
        private String username;
        private String displayName;
    }
  2. 数据格式化:转换数据库原始数据

    java 复制代码
    // 数据库存储的原始日期
    private Date createTime; 
    
    // VO中的格式化日期
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
    private String createTime;
  3. 减少网络传输:只返回必要字段

    java 复制代码
    // 不返回大型字段
    // private byte[] avatarImage; 
  4. 数据组合:聚合多个Entity的数据

    java 复制代码
    public class OrderDetailVO {
        private OrderVO order;
        private List<OrderItemVO> items;
        private UserVO user;
    }
一些错误写法

错误1:直接返回Entity

java 复制代码
// Controller中
public User getUser() {
    return userService.getUser(); // 返回包含密码的Entity
}

正确做法:返回VO

java 复制代码
public UserVO getUser() {
    User user = userService.getUser();
    return convertToVO(user);
}

错误2:DTO/VO混用

java 复制代码
public class UserDTO {
    // 请求字段
    private String password;
    
    // 响应字段
    private String createTime;
}

正确做法:DTO/VO分离

java 复制代码
// 请求专用
public class UserRequestDTO {
    private String username;
    private String password;
}

// 响应专用
public class UserResponseVO {
    private String username;
    private String createTime;
}
总结要点
  1. 分层结构

    • Controller:处理HTTP请求/响应

    • Service:实现业务逻辑

    • Mapper:数据库操作

    • Entity:映射数据库表

    • DTO:接收请求数据

    • VO:返回响应数据

  2. 数据流转方向

    前端 → DTO → Controller → Service → Mapper → Entity → 数据库

    数据库 → Entity → Mapper → Service → VO → Controller → 前端

  3. 核心原则

    • 永远不要直接返回Entity给前端

    • 各层只处理本层的职责

    • DTO用于输入,VO用于输出

    • Service处理业务逻辑和类型转换

  4. 转换工具推荐

    • 简单项目:BeanUtils.copyProperties()

    • 复杂项目:MapStruct(自动生成转换代码)

通过这样的分层设计,你的代码将更加清晰、安全且易于维护。每个层专注自己的职责,使整个系统像精密的齿轮一样协同工作。

相关推荐
你的人类朋友2 小时前
🤔Token 存储方案有哪些
前端·javascript·后端
烛阴2 小时前
从零开始:使用Node.js和Cheerio进行轻量级网页数据提取
前端·javascript·后端
liuyang___2 小时前
日期的数据格式转换
前端·后端·学习·node.js·node
bxlj_jcj2 小时前
深入剖析Debezium:CDC领域的“数据魔法棒”
java·架构
元気いっぱいの猫2 小时前
Spring Cloud 微服务架构实战指南 -- SpringCLoud概述
spring cloud·微服务·架构
孙克旭_3 小时前
day032-网站集群架构与环境准备
linux·运维·架构·自动化
保持学习ing4 小时前
SpringBoot前后台交互 -- 登录功能实现(拦截器+异常捕获器)
java·spring boot·后端·ssm·交互·拦截器·异常捕获器
七七&5564 小时前
【Java开发日记】基于 Spring Cloud 的微服务架构分析
java·spring cloud·架构
猕员桃4 小时前
《Spring Boot 微服务架构下的高并发活动系统设计与实践》
spring boot·微服务·架构
十年老菜鸟5 小时前
spring boot源码和lib分开打包
spring boot·后端·maven