Entity、DTO、VO 边界
Forge 后端使用三层对象模型来分离数据库映射、请求参数和响应数据。你需要明确每层使用哪个对象,避免混用。
三层对象职责
| 对象 | 职责 | 所在包 | 使用层 |
|---|---|---|---|
| Entity | 映射数据库表 | entity/ | Service、Mapper |
| DTO | 接收请求参数 | dto/ | Controller 参数 |
| VO | 返回响应数据 | vo/ | Controller 返回值 |
Entity
Entity 直接映射数据库表,每个字段对应一个数据库列:
java
@Data
@TableName("biz_order")
public class OrderEntity {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private Long tenantId;
private String orderNo;
private Long amount;
private String status;
@TableLogic(value = "0", delval = "id")
@TableField("del_flag")
private Long delFlag;
private Long createBy;
private LocalDateTime createTime;
private Long updateBy;
private LocalDateTime updateTime;
}DTO
DTO 用于接收前端请求参数,只包含请求需要的字段:
java
@Data
public class OrderDTO {
private Long id;
private String orderNo;
private Long amount;
private String status;
}分页查询 DTO 继承 PageQuery:
java
@Data
@EqualsAndHashCode(callSuper = true)
public class OrderQueryDTO extends PageQuery {
private String orderNo;
private String status;
}VO
VO 用于返回前端响应数据,可以组合多个表的字段:
java
@Data
public class OrderVO {
private Long id;
private String orderNo;
private Long amount;
private String status;
private String statusLabel; // 字典翻译后的标签
private String createByName; // 关联用户名
private LocalDateTime createTime;
}对象转换
使用 BeanUtils 进行对象转换:
java
// Entity → VO
OrderVO vo = new OrderVO();
BeanUtils.copyProperties(entity, vo);
// DTO → Entity
OrderEntity entity = new OrderEntity();
BeanUtils.copyProperties(dto, entity);批量转换:
java
List<OrderVO> voList = entityList.stream().map(entity -> {
OrderVO vo = new OrderVO();
BeanUtils.copyProperties(entity, vo);
return vo;
}).collect(Collectors.toList());各层使用规则
| 层 | 输入 | 输出 |
|---|---|---|
| Controller | DTO | RespInfo 或 PageResult 包装 |
| Service | DTO / 基本类型 | Entity / VO / PageResult (泛型) |
| Mapper | Entity / 基本类型 | Entity / List (泛型) |
禁止事项
- 禁止 Controller 直接返回 Entity
- 禁止 Mapper 方法参数使用 DTO
- 禁止 Entity 传递到前端
- 禁止 DTO 和 VO 混用(接收和返回必须是不同对象)
金额字段
金额字段使用 Long 类型,单位分:
java
// Entity
private Long amount; // 金额,单位分
// DTO
private Long amount;
// VO
private Long amount;
private String amountYuan; // 可选:前端展示用的元