You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DTO(数据传输对象)与Model类的区别解析及示例需求

Model类与DTO的区别及示例

先明确核心差异:

  • Model:是业务实体类,不仅包含数据字段,还封装了和该实体相关的业务逻辑,直接服务于业务规则;
  • DTO(数据传输对象):仅作为数据传输的容器,只有数据字段和基础的读写方法,完全不包含业务逻辑,用于在不同系统/层级间传递数据。

示例1:Model类(以用户业务为例)

import java.time.LocalDate;
import java.time.Period;
import org.mindrot.jbcrypt.BCrypt;

public class UserModel {
    // 与用户业务相关的核心数据字段
    private Long id;
    private String username;
    private String encryptedPassword; // 存储加密后的密码,属于业务敏感数据
    private LocalDate birthDate;

    // 构造方法:初始化业务实体
    public UserModel(Long id, String username, String encryptedPassword, LocalDate birthDate) {
        this.id = id;
        this.username = username;
        this.encryptedPassword = encryptedPassword;
        this.birthDate = birthDate;
    }

    // 业务逻辑方法:计算用户当前年龄(和业务规则绑定)
    public int calculateAge() {
        return Period.between(this.birthDate, LocalDate.now()).getYears();
    }

    // 业务逻辑方法:验证用户输入的密码是否正确(业务规则实现)
    public boolean verifyPassword(String rawPassword) {
        return BCrypt.checkpw(rawPassword, this.encryptedPassword);
    }

    // 仅暴露业务允许访问的字段的getter
    public Long getId() { return id; }
    public String getUsername() { return username; }
    public int getAge() { return calculateAge(); }
}

这个UserModel是业务层直接操作的对象,核心是承载业务逻辑:比如计算年龄、验证密码都是和用户业务强相关的规则,而非单纯存储数据。

示例2:DTO类(数据传输用)

场景1:前端注册用户时的请求DTO

import java.time.LocalDate;

public class UserRegisterDTO {
    // 仅包含前端注册时需要提交的数据字段
    private String username;
    private String rawPassword; // 前端传入的明文密码,仅用于传输
    private String email;
    private LocalDate birthDate;

    // 空构造、全参构造:用于框架序列化/反序列化数据
    public UserRegisterDTO() {}
    public UserRegisterDTO(String username, String rawPassword, String email, LocalDate birthDate) {
        this.username = username;
        this.rawPassword = rawPassword;
        this.email = email;
        this.birthDate = birthDate;
    }

    // 所有字段的getter/setter:仅用于读写传输的数据
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getRawPassword() { return rawPassword; }
    public void setRawPassword(String rawPassword) { this.rawPassword = rawPassword; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public LocalDate getBirthDate() { return birthDate; }
    public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; }
}

场景2:后端返回给前端的用户信息DTO

public class UserResponseDTO {
    // 仅包含前端需要展示的字段,隐藏敏感数据(比如加密密码)
    private String username;
    private int age;
    private String email;

    public UserResponseDTO(String username, int age, String email) {
        this.username = username;
        this.age = age;
        this.email = email;
    }

    // 仅提供前端需要的字段的getter
    public String getUsername() { return username; }
    public int getAge() { return age; }
    public String getEmail() { return email; }
}

这两个DTO类没有任何业务逻辑,仅负责在前后端之间传递数据:

  • UserRegisterDTO用来接收前端的注册请求数据,之后业务层会把它转换成UserModel(比如对明文密码加密后存储);
  • UserResponseDTO则是把UserModel处理后的结果,抽取出前端需要的字段返回,避免暴露敏感数据(比如加密密码)。

总结差异

维度Model类DTO类
核心定位业务实体,承载业务逻辑数据传输容器,仅传数据
逻辑包含有业务逻辑方法(计算、校验等)无任何业务逻辑,仅get/set
使用场景业务层内部处理业务逻辑时使用跨层/跨系统传递数据时使用
字段范围包含业务所需的全部字段(含敏感字段)仅包含传输所需的必要字段

内容的提问来源于stack exchange,提问作者Dhanush S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:38:11