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类的对象向前端传递数据,会有什么问题?
- 不需要的字段也会传递到前端页面。
如password、registerIp、loginIp和loginDate这几个字段我们可能在前端根本不需要展示,但是这些字段有可能也会被传递到前端(除非我们在SQL查询的时候没有查询出对应的字段)。这不仅使数据的传输量增大,还可能有安全性问题。 - 某些字段需要转换,但是无法支持。
对于上面例子中的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;
}
}