天天看點

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

作者:程式猿久一

POJO 的定義是無規則簡單的對象,在日常的代碼分層中 pojo 會被分為VO、BO、 PO、 DTO

VO (view object/value object)表示層對象

1、前端展示的資料,在接口資料傳回給前端的時候需要轉成VO

2、個人了解使用場景,接口層服務中,将DTO轉成VO,傳回給前台

B0(bussines object)業務層對象

1、主要在服務内部使用的業務對象

2、可以包含多個對象,可以用于對象的聚合操作

3、個人了解使用場景,在服務層服務中,由DTO轉成BO然後進行業務處理後,轉成DTO傳回到接口層

PO(persistent object)持久對象

1、出現位置為資料庫資料,用來存儲資料庫提取的資料

2、隻存儲資料,不包含資料操作

3、個人了解使用場景,在資料庫層中,擷取的資料庫資料存儲到PO中,然後轉為DTO傳回到服務層中

DTO(Data Transfer Object)資料傳輸對象

1、在服務間的調用中,傳輸的資料對象

2、個人了解,DTO是可以存在于各層服務中(接口、服務、資料庫等等)服務間的互動使用DTO來解耦

DO(domain object)領域實體對象

DO 現在主要有兩個版本:

①阿裡巴巴的開發手冊中的定義,DO( Data Object)這個等同于上面的PO

②DDD(Domain-Driven Design)領域驅動設計中,DO(Domain Object)這個等同于上面的BO

參考文檔:

https://juejin.cn/post/6952848675924082718
https://juejin.cn/post/6844904046097072141
https://zhuanlan.zhihu.com/p/264675395           

插件名稱:Simple Object Copy

1. 定義方法出入參

2. 光标定位方法内,使用快捷鍵ALT+INSERT(WIN) 、 command + N(mac) ,或者右鍵滑鼠選擇Generate,彈出生成選項框後,選擇genCopyMethod,代碼就生成好了

需要手寫的代碼

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

一鍵生成後的展示

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

複雜對象轉化展示(一鍵生成後的展示)

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

複雜對象轉化源碼示例:

@Data
public class UserVO {
private String name;
private Date entryDate;
private String userId;
private List<RoleVO> roleList;
private RoomVO room;
public static UserVO convertToUserVO(UserDTO item) {
if (item == ) {
return ;
}
UserVO result = new UserVO;
result.setName(item.getName);
result.setEntryDate(item.getEntryDate);
result.setUserId(item.getUserId);
List<RoleDTO> roleList = item.getRoleList;
if (roleList == ) {
result.setRoleList;
} else {
result.setRoleList(roleList.stream.map(UserVO::convertToRoleVO).collect(Collectors.toList);
}
result.setRoom(convertToRoomVO(item.getRoom));
return result;
}

public static RoomVO convertToRoomVO(RoomDTO item) {
if (item == ) {
return ;
}
RoomVO result = new RoomVO;
result.setRoomId(item.getRoomId);
result.setBuildingId(item.getBuildingId);
result.setRoomName;
result.setBuildingName;
return result;
}

public static RoleVO convertToRoleVO(RoleDTO item) {
if (item == ) {
return ;
}
RoleVO result = new RoleVO;
result.setRoleId(item.getRoleId);
result.setRoleName(item.getRoleName);
result.setCreateTime(item.getCreateTime);
return result;
}
}
@Data
public class UserDTO {
private String name;
private Date entryDate;
private String userId;
private List<RoleDTO> roleList;
private RoomDTO room;
}

@Data
public class RoleVO {
private String roleId;
private String roleName;
private LocalDateTime createTime;
}

@Data
public class RoleDTO {
private String roleId;
private String roleName;
private LocalDateTime createTime;
}

@Data
public class RoomVO {
private String roomId;
private String buildingId;
private String roomName;
private String buildingName;

}

@Data
public class RoomDTO {
private String roomId;
private String buildingId;
}           

1.無入侵市面上有很多類似的工具類,比較常用的有

1、Spring BeanUtils (copyProperties)

2、Cglib BeanCopier (copyProperties)

3、Apache BeanUtils (copyProperties)

4、Apache PropertyUtils (copyProperties)

5、Dozer

6、mapstruct

7、JSON 序列化 再反序列化

這些工具,不僅要引入相應的依賴jar包,而且對代碼有入侵,要調用對應得api方法才能進行轉化,一旦遇到類型不一緻,字段名稍有變動,就需要另寫java代碼補全字段,整體代碼非常醜陋。

舉例:

1. mapstruct

同樣的代碼,,不僅要引入依賴、寫如下轉化mapper,還要,在對應地方調用對應api(代碼入侵驗證),然而Simple Object Copy 隻需要一鍵生成。

RoomDTO中不存在的roomName、buildingName還要mapstruct另寫方法,很容易忽略。源實體中不存在的屬性,沒有提示,小心前端總是問為啥都是。

在Simple Object Copy 插件代碼生成後,不存在的字段也生成了空方法,直接編譯提示補充,不容易忽略

需要手寫的代碼:

@Mapper(componentModel = "spring",uses = {RoleVOMapper.class,RoomVOMapper.class})
publicinterfaceUserMapper{
UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);

UserVO toUserVO(UserDTO userDTO);
}

@Mapper(componentModel = "spring")
publicinterfaceRoleMapper{
RoleVO toRoleVO(RoleDTO roleDTO);
}

@Mapper(componentModel = "spring")
publicinterfaceRoomMapper{
RoomVO toRoomVO(RoomDTO roomDTO);
}


publicclassMain{
publicstaticvoidmain(String[] args) {
UserDTO user = ;
UserVO userVO = UserMapper.INSTANCE.toUserVO(user);
userVO.getRoomVO.setRoomName("大廳1");
userVO.getRoomVO.setBuildingName("尚德樓");
}
}           

1. BeanUtils

性能稍差。

不支援複雜對象還是要寫大量代碼,代碼字段不清晰不易了解,别人接手難。RoomDTO中不存在的roomName、buildingName還要BeanUtils另寫方法,很容易忽略。源實體中不存在的屬性,沒有提示,小心前端總是問為啥都是。

@Data
publicclassUserVO{
private String name;
private Date entryDate;
private String userId;
private List<RoleVO> roleList;
private RoomVO room;
public static UserVO convertToUserVO(UserDTO item) {
if (item == ) {
return ;
}
UserVO result = new UserVO;
BeanUtils.copyProperties(item,result);
List<RoleDTO> roleList = item.getRoleList;
if (roleList == ) {
result.setRoleList;
} else {
result.setRoleList(roleList.stream.map(UserVO::convertToRoleVO).collect(Collectors.toList);
}
result.setRoom(convertToRoomVO(item.getRoom));
return result;
}

public static RoomVO convertToRoomVO(RoomDTO item) {
if (item == ) {
return ;
}
RoomVO result = new RoomVO;
BeanUtils.copyProperties(item,result);

result.setRoomName;
result.setBuildingName;
return result;
}

public static RoleVO convertToRoleVO(RoleDTO item) {
if (item == ) {
return ;
}
RoleVO result = new RoleVO;
BeanUtils.copyProperties(item,result);
return result;
}
}           

2.性能優勢

相比上面的工具類,不是使用反射、就是是用代理、序列化操作。相比于純正的set方法去轉化,差距不是一個量級。此次不贅述。

3.靈活性、相容性

跟上述工具類相比插件有很大優勢,不再贅述,下面我們比較一下,我之前常用的idea插件generateO2O

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

在此推薦其他一個我常用插件:generateAllSetter,搭配食用更佳,

4. 如何下載下傳?

打開idea plugins,切market place 搜尋:Simple Object Copy

一款 IDEA 插件幫你優雅轉化 DTO、VO、BO、PO、DO

來源:juejin.cn/post/7053264631262871583