💡 一则也许对你有用的小广告 🏆

欢迎飞飞程序员   ,你将获得:专属的实战项目(已更新的所有会员标识的项目都能学习) / 1v1 提问 / Java 学习路线 / PHP 学习路线 / 学习打卡 / 社群讨论

  • 正在进行中的项目:《FFBlog知识付费博客项目》 正在持续更新中,基于 Spring Boot 3.x + JDK 21...,点击查看 ;
  • 《从零开发:FFBlog知识付费博客项目(全栈开发)》 演示链接: https://ffblog.ffcxy.com/  ;

截止目前, 飞飞  正在疯狂爆肝实战项目,后续还会上新更多项目,目标是将所学知识开发成项目并且分享给大家,如知识付费系统, Ai系统, CMS系统,在线商城系统,等等 ,欢迎点击围观

DO Mapper Vo Controller Service 是Java后端分层架构,通常在Spring Boot项目中使用,旨在实现“高内聚、低耦合”,让代码职责分明,便于维护。

下面我将按照数据流向从下到上,或者从外到内为您分别介绍这几层。


1. DO (Data Object) - 数据对象

  • 定义:通常与数据库表结构一一对应。它是持久化层的实体,数据库里有什么字段,DO里就有什么字段(或者基本对应)。
  • 职责:单纯地承载数据,不包含业务逻辑。
  • 例子:
    • 假设数据库有一张表 t_user,字段有 id, user_name, password, create_time。
    • 那么 UserDO 类就应该有这些属性:
      public class UserDO {
          private Long id;
          private String userName;
          private String password;
          private Date createTime;
          // getter/setter...
      }
      

2. Mapper (DAO层) - 数据访问层

  • 定义:也叫DAO(Data Access Object)层。它是与数据库直接打交道的层。
  • 职责:负责SQL的执行。它从数据库查询数据封装成DO,或者把DO保存进数据库。
  • 例子:

    • 使用 MyBatis 时,你会写一个接口 UserMapper:

      public interface UserMapper {
          // 根据ID查询用户,返回的是 DO
          UserDO selectById(Long id);
                  
          // 插入用户
          int insert(UserDO user);
      }
      

3. VO (View Object) - 视图对象

  • 定义:通常用于前端展示(View)。它是专门给前端接口返回的数据结构。
  • 职责:隐藏敏感信息(如密码),或者对数据格式进行转换(如把日期格式化成字符串,把性别 1 转换成 "男")。
  • 例子:
    • 前端只需要显示用户昵称和注册时间,不需要密码。
    • 定义 UserVO:
      public class UserVO {
          private String nickName;     // 可能是 userName 的别名
          private String registerDate; // 格式化后的日期,而不是原始时间戳
          // 注意:这里没有 password 字段
      }
      

4. Service - 业务逻辑层

  • 定义:核心业务逻辑层。它是整个系统的“大脑”。
  • 职责:
    • 处理复杂的业务规则(如计算、校验)。
    • 协调多个 Mapper(比如转账需要同时操作两个账户)。
    • 进行事务控制(Transaction)。
    • 将 DO 转换为 VO。
  • 例子:
    • 用户注册功能:
      1. 检查用户名是否已存在(调用 Mapper)。
      2. 如果不存在,加密密码。
      3. 构建 UserDO 并保存(调用 Mapper)。
      4. 发送欢迎邮件。
        @Service
        public class UserService {
        public void register(String name, String pwd) {
            // 1. 校验逻辑
            if (userMapper.selectByName(name) != null) {
                throw new RuntimeException("用户已存在");
            }
            // 2. 业务逻辑:加密
            String encryptedPwd = MD5Util.encrypt(pwd);
            // 3. 组装 DO
            UserDO user = new UserDO();
            user.setUserName(name);
            user.setPassword(encryptedPwd);
            // 4. 持久化
            userMapper.insert(user);
        }
        }
        

5. Controller - 控制层

  • 定义:系统的入口,直接面对前端(浏览器/APP)。
  • 职责:
    • 接收HTTP请求,解析参数。
    • 调用 Service 层处理业务。
    • 将结果封装成统一的格式(如 JSON)返回给前端。
    • 通常不写复杂的业务逻辑。
  • 例子:

    • 前端发起 POST /user/register 请求。

      @RestController
      @RequestMapping("/user")
      public class UserController {
                  
          @Autowired
          private UserService userService;
      
          @PostMapping("/register")
          public Result register(@RequestBody UserRegisterReq req) {
              // 调用 Service
              userService.register(req.getName(), req.getPassword());
              // 返回成功信息
              return Result.success("注册成功");
          }
      }
      

一个完整的“用户查询”流程示例

为了让你更清晰地理解它们是如何协作的,我们来看一个“根据ID查询用户信息”的流程:

  1. 用户点击前端按钮,发起请求。
  2. Controller 接收到请求 GET /user/1。
  3. Controller 调用 Service 的 getUserById(1) 方法。
  4. Service 调用 Mapper 的 selectById(1) 方法。
  5. Mapper 执行 SQL SELECT * FROM t_user WHERE id = 1,数据库返回数据。
  6. Mapper 将数据库记录封装成 DO (UserDO) 返回给 Service。
  7. Service 拿到 UserDO,发现里面有密码字段,为了安全,它创建一个 VO (UserVO),把 UserDO 里的昵称和时间复制进去,丢弃密码。
  8. Service 将 UserVO 返回给 Controller。
  9. Controller 将 UserVO 包装成 JSON 格式返回给前端。

示例流程如下:

前端 <--> Controller <--> Service <--> Mapper <--> 数据库
              (VO/DTO)     (DO/VO)     (DO)
上一篇 SpringBoot框架Lombok库中常用的注解详解和用法
下一篇 什么是 AOP 面向切面编程?

全部评论(0)

头像
😃 😁 😅 😂 😍 😜 😝 🤑 🥵 🥰 😙 😎 😵 😭 😱 😖 🥳 👽 🙈 🤡 😤 💣 💯 💢 ❤️ 👍 👏 👋 👌 🤏 🙏
还没有任何评论哟~
微信扫一扫
微信二维码
微信客服
QQ 咨询
QQ二维码
工作日 9:00 - 18:00 在线
QQ客服
在线工单
提交问题工单,我们会尽快回复处理。
提交工单
在线工单