VO、DO、DTO的设计以及它们之间的转换

1.概念

VO(View Object):视图对象,一般位于Controller层,用于展示视图。

DO(Domain Object):数据对象,就是从现实世界中抽象出来的有形或无形的业务实体。

DTO(Data Transfer Object):数据传输对象,用于展示层与服务层之间的数据传输对象。


在日常的项目开发中,VO对应于页面上需要显示的数据(表单),DO对应于数据库中存储的数据(数据表),DTO对应于除二者之外需要进行传递的数据。在一些小项目中,对于一种业务实体,封装成一个DO就够了。


2.VO与DO的设计

实体类MemberUserDO

public class MemberUserDO extends TenantBaseDO {

    /**
     * 用户ID
     */
    @TableId
    private Long id;
    /**
     * 用户昵称
     */
    private String nickname;
    /**
     * 用户头像
     */
    private String avatar;
    /**
     * 帐号状态
     *
     * 枚举 {@link CommonStatusEnum}
     */
    private Integer status;

    /**
     * 手机
     */
    private String mobile;

    /**
     * 用户角色:0-游客 1-学生 2-导师
     */
    private Integer role;
    /**
     * 微信openid
     */
    private String openid;

    /**
     * 加密后的密码
     *
     * 因为目前使用 {@link BCryptPasswordEncoder} 加密器,所以无需自己处理 salt 盐
     */
    private String password;
    /**
     * 注册 IP
     */
    private String registerIp;
    /**
     * 最后登录IP
     */
    private String loginIp;
    /**
     * 最后登录时间
     */
    private LocalDateTime loginDate;

}

如果用MemberUserDO类的对象向前端传递数据,会有什么问题?

  1. 不需要的字段也会传递到前端页面。
    如password、registerIp、loginIp和loginDate这几个字段我们可能在前端根本不需要展示,但是这些字段有可能也会被传递到前端(除非我们在SQL查询的时候没有查询出对应的字段)。这不仅使数据的传输量增大,还可能有安全性问题。
  2. 某些字段需要转换,但是无法支持。
    对于上面例子中的role字段,我们在数据库中存储的是数字,但是在前端页面我要展示的是中文描述。这种情况只能在前端通过if/else的方式来分情况展示。

引入VO(例如前端需要获取用户基本信息)

@Schema(description = "用户 APP - 用户个人信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppUserInfoRespVO {

    @Schema(description = "用户昵称", required = true, example = "小沈")
    private String nickname;

    @Schema(description = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952")
    private String avatar;

    @Schema(description = "用户手机号", required = true, example = "15601691300")
    private String mobile;
}

3.DO与VO之间的转换

在ruoyi-vue-pro中通过convert进行转换

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-03-05T09:59:07+0800",
    comments = "version: 1.5.3.Final, compiler: javac, environment: Java 15.0.2 (Oracle Corporation)"
)
public class UserConvertImpl implements UserConvert {
  
    @Override
    public AppUserInfoRespVO convert(MemberUserDO bean) {
        if ( bean == null ) {
            return null;
        }

        AppUserInfoRespVO appUserInfoRespVO = new AppUserInfoRespVO();

        appUserInfoRespVO.setNickname( bean.getNickname() );
        appUserInfoRespVO.setAvatar( bean.getAvatar() );
        appUserInfoRespVO.setMobile( bean.getMobile() );

        return appUserInfoRespVO;
    }
  
}

你可能感兴趣的:(java,java,后端)