后端开发中的分层思想,DAO、Service、Controller、Mapper,VO、DTO、DO、PO每层的作用及调用关系

在后端开发中,应用通常采用分层架构来组织代码,以实现更好的可维护性和可扩展性。在这个架构中,常见的数据传输对象(DTO)、数据对象(DO)、值对象(VO)、持久化对象(PO)及各种层如DAO(数据访问对象)、Service(服务层)、Controller(控制器)和Mapper等都有其特定的角色和职责。下面是每一层和对象的具体解释以及它们之间的调用关系的示例。

各层的职责和角色

Controller(控制器层)

职责: 处理HTTP请求并返回HTTP响应。它接收请求参数,调用相应的Service,并将返回的数据返回给客户端。

调用关系: 通常由前端发送请求调用。

Service(服务层)

职责: 业务逻辑处理层,负责具体的业务逻辑,调用DAO层进行数据访问。

调用关系: 通常由Controller调用,同时也可能调用其他Service。

DAO(数据访问对象)

职责: 数据存取层,负责与数据库进行交互,如增、删、改、查操作。它封装了对数据持久化存储的操作。

调用关系: 由Service调用。

Mapper(映射器)

职责: 用于数据库操作的映射工具,通常用来将数据库表和对象进行映射(如MyBatis中的Mapper)。

调用关系: 由DAO调用,负责将DO和PO之间的转换。

DTO(数据传输对象)

职责: 表示请求或响应的数据结构,通常用于传递数据,尤其是在网络传输时。DTO不应该包含业务逻辑。

调用关系: 通常由Controller和Service使用。

VO(值对象)

职责: 表示一组数据的值,不强调身份,通常用于业务逻辑层,承载业务逻辑计算的结果。

调用关系: 通常在Service层用到。

DO(数据对象)

职责: 表示与数据库表直接对应的对象。它通常在数据访问层进行操作。

调用关系: 由DAO使用,表示数据库中的一行数据。

PO(持久化对象)

职责: 持久化到数据库的对象,一般与DO类似,但在ORM框架中更强调其持久化属性。

调用关系: 通常是DAO和Mapper中的数据实体。

举个具体例子:

假设我们正在开发一个简单的用户管理系统,以下是如何使用这些层和对象的示例。

用户管理流程示例:
1. Controller:UserController

javascript 复制代码
// An highlighted block
@RestController
@RequestMapping("/api/users")
public class UserController {
    
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
        UserDTO createdUser = userService.createUser(userDTO);
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
}

2. Service:UserService

javascript 复制代码
// An highlighted block
@Service
public class UserService {

    private final UserDAO userDAO;

    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public UserDTO createUser(UserDTO userDTO) {
        UserDO userDO = new UserDO(userDTO.getName(), userDTO.getEmail());
        userDAO.save(userDO);
        return new UserDTO(userDO.getId(), userDO.getName(), userDO.getEmail());
    }
}

3. DAO:UserDAO

javascript 复制代码
// An highlighted block
@Repository
public class UserDAO {

    private final UserMapper userMapper;

    public UserDAO(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public void save(UserDO userDO) {
        userMapper.insert(userDO);
    }
}

4. Mapper:UserMapper (MyBatis接口)

javascript 复制代码
// An highlighted block
@Mapper
public interface UserMapper {
    void insert(UserDO userDO);
}

5. Data Object(DO)

javascript 复制代码
// An highlighted block
public class UserDO {
    private Long id;
    private String name;
    private String email;

    // Constructor, getters, setters...
}

6.数据传输对象(DTO)

javascript 复制代码
public class UserDTO {
    private Long id;
    private String name;
    private String email;

    // Constructor, getters, setters...
}

调用顺序:

  • 用户通过HTTP POST请求调用 UserController.createUser 方法。
  • UserController 接收请求体中的 UserDTO,并将其传递给 UserService.createUser 方法。
  • UserService 将 UserDTO 转换为 UserDO,然后调用 UserDAO.save 方法。
  • UserDAO 使用 UserMapper 执行数据库插入操作。
  • 数据库操作完成后,结果返回到 UserService,最后返回到 UserController,并发送给客户端。
相关推荐
独孤九剑打醒他2 小时前
双层Master-Worker软硬协同调度架构:从根源解决分布式数据一致性难题
后端·嵌入式硬件·硬件架构·硬件工程
宠友信息3 小时前
多端数据互通场景下Spring Boot仿小红书源码结构设计
数据库·spring boot·redis·缓存·架构
不会c+3 小时前
02-SpringBoot配置文件
java·spring boot·后端
雨辰AI4 小时前
生产级实战:人大金仓 V9 标准化运维手册(日常巡检 + 监控告警 + 应急处置)
java·运维·数据库·后端
TeamDev5 小时前
JxBrowser 9.3.0 版本发布啦!
java·后端·c#·混合应用·jxbrowser·浏览器控件·异步媒体设备
陈随易5 小时前
Rust、Golang、MoonBit 编译成 WASM,体积和速度差距有多大?
前端·后端·程序员
IT_陈寒5 小时前
Python多线程的坑,我居然现在才踩到
前端·人工智能·后端
格子软件6 小时前
2026年GEO优化系统源码解构:核心状态机与高并发流控深度剖析
java·vue.js·spring boot·vue·geo
魏祖潇6 小时前
DDD 完整指南——AI 时代工程师的第一道秩序分水岭
人工智能·后端
im_lanny6 小时前
如何给 Agent 打造“最强大脑“?深度解析短期记忆与长期记忆的分层设计
后端