PO VO BO对象整理
网上有很多这样的文章,但是都没有例子。我结合着实验室项目中的代码片段来把这部分内容展示的更形象一点。
需要提一嘴的是,PO JO BO等是相对抽象的软件开发概念,可以使用多种语言来实现,这里仅使用java语言作为示范
POJO
就是一个普通的java对象
PO
PO: persistent object 持久对象
一个PO对象与一条数据库中的数据相对应。
在SpringBoot中,po对象可以加注解来指定对应数据库中的哪张表,也正说明了上面的解释。下面分别给出PO对象以及数据库中的表,大家可以感受一下。
PO对象(系统用户)
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "tb_sys_user")
public class SysUser extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 所属公司、商家
*/
Long corp;
/**
* 用户名
*/
private String username;
/**
* 手机号
*/
private String phone;
/**
* 密码
*/
private String password;
/**
* 状态
*/
private Integer status;
}
tb_sys_user表
可以看到,他们两个的字段是一一对应的。(create_time在BaseEntity中,SysUser继承了该类)
VO
VO:value object 值对象 / view object 表现层对象
VO主要用来与视图层打交道,可以是web页面,或者swing页面。
在web页面中,由前端传来的数据往往由VO进行保存
还是上面的系统用户,它的VO长这样子。
@Data
public class UserVO {
private Long id;
Long corp;
private String username;
private String phone;
private Integer status;
private String creator;
private Long createTime;
private String updater;
private Long updateTime;
private Set<String> roles;
}
仔细看看会发现,这里多了一个roles字段,为set<String>
类型,但是在PO对象中没有这个字段。这是因为,在数据库中这个字段被抽离到了一个新的PO中(其实也可以不抽离的,不是重点)。
重点在于,由于PO对象不能直接储存set<String>
类型,因为mysql中默认不支持此类型。所以在实际储存时,我们采用了使用逗号分隔的方式来将其转化成字符串存储。
如下,这是储存role的PO,里面的name字段就是储存原来set<String>
的字符串
@EqualsAndHashCode(callSuper = true)
@Data
@Entity
@DynamicInsert
@DynamicUpdate
@Table(name = "tb_sys_role")
public class SysRole extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 所属公司、商家
*/
Long corp;
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 状态
*/
private Integer status;
}
BO
BO:business object 业务对象。
网上的观点杂乱不清,因为实际上BO对象也没有一个准确的定义。大家不妨来瞅一瞅他的名字,业务对象
,这个定义本身就很模棱两可,似乎能完成一定业务逻辑的都可以叫做BO。在我们的项目中,是这样来使用BO对象的。
即存在这样一种场景,PO对象记录了数据库中的数据,但是并不能直接返回给前端(例如上面把set<String>
转化成了字符串,总不能直接返回一个字符串吧。)。于是就把PO对象进行处理之后转化成了可以直接返回给前端的BO对象。
当然,BO对象不仅仅承担类型转化的任务,还可以同时记录多个PO的信息,一起返回给前端。
总得来说,前端需要什么,BO就记录什么。
在项目中,以下代码定义了一个UserInfo的Bo对象
@Data
public class UserInfo {
private String name;
private Set<String> roles;
private Set<Long> permissions;
}
将PO对象转化为BO对象的代码如下
@Override
public UserInfo getInfo(Long userId) {
SysUser sysUser = sysUserDao.findById(userId).orElse(null);
if (sysUser == null) {
throw new BusinessException("用户不存在");
}
UserInfo userInfo = new UserInfo();
userInfo.setName(sysUser.getUsername());
List<SysUserRole> userRoles = sysUserRoleDao.findAllByUserId(userId);
Set<String> roles = new HashSet<>(userRoles.size());
Set<Long> roleIds = new HashSet<>(userRoles.size());
for (SysUserRole userRole : userRoles) {
sysRoleDao.findById(userRole.getRoleId()).ifPresent(sysRole -> {
roles.add(sysRole.getCode());
roleIds.add(sysRole.getId());
});
}
userInfo.setRoles(roles);
userInfo.setPermissions(sysRoleService.listAllPermIdsByRoleIds(roleIds));
return userInfo;
}