An IDEA plug-in helps you elegantly transform DTO, VO, BO, PO, and DO

Because the official account has changed the push rules, please click “Looking” and add “star” to get exciting technology sharing as soon as possible

Click to follow the #InternetArchitect official account and get the full set of architect information here  110114f0dd87f63880a25b26f3c4edf5.png

0,2T architect learning materials dry content

Previous article: Sharing of useful learning materials for 2T architects

Hi everyone, I am an Internet Architect!

The definition of POJO is an irregular and simple object. In daily code layering, pojo will be divided into VO, BO, PO, and DTO.

VO (view object/value object) presentation layer object

1. The data displayed on the front end needs to be converted into VO when the interface data is returned to the front end.

2. Personally understand the usage scenario. In the interface layer service, convert DTO into VO and return it to the front desk.

B0 (bussines object) business layer object

1. Business objects mainly used within the service

2. It can contain multiple objects and can be used for object aggregation operations.

3. Personally understand the usage scenario. In the service layer service, DTO is converted into BO and then after business processing, it is converted into DTO and returned to the interface layer.

PO (persistent object) persistent object

1. The location is database data, which is used to store data extracted from the database.

2. Only stores data, does not include data operations

3. Personally understand the usage scenario. In the database layer, the obtained database data is stored in PO, and then converted into DTO and returned to the service layer.

DTO (Data Transfer Object) data transfer object

1. In calls between services, the data objects transferred

2. Personal understanding is that DTO can exist in various layers of services (interfaces, services, databases, etc.). The interaction between services uses DTO to decouple it.

DO (domain object) domain entity object

There are currently two main versions of DO:

①The definition in Alibaba’s development manual, DO (Data Object) is equivalent to the PO above

②In DDD (Domain-Driven Design) domain-driven design, DO (Domain Object) is equivalent to the BO above

Plug-in name: Simple Object Copy

  • Define method input and output parameters

  • In the cursor positioning method, use the shortcut keys ALT + INSERT(WIN), command + N(mac), or right-click the mouse and select Generate. When the generation option box pops up, select genCopyMethod, and the code will be generated.

Requires handwritten code

408b25ca0e1244990047c29fccd11967.png

Display after one-click generation

41d9870c9a318aea50c442885dc7f7f1.png

Complex object transformation display (display after one-click generation)

2e3edbaa9f1bbdc59c1836d254bb9ff4.png

Complex object conversion source code example:

@Datapublic 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 == null) { return null ; } UserVO result = new UserVO(); result.setName(item.getName()); result.setEntryDate(item.getEntryDate()); result.setUserId(item.getUserId()); List<RoleDTO> roleList = item .getRoleList(); if (roleList == null) { result.setRoleList(null); } 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 == null) { return null; } 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 == null) { return null; } RoleVO result = new RoleVO(); result.setRoleId(item.getRoleId()); result.setRoleName(item.getRoleName()); result.setCreateTime(item.getCreateTime()); return result ; }}@Datapublic class UserDTO { private String name; private Date entryDate; private String userId; private List<RoleDTO> roleList; private RoomDTO room;}@Datapublic class RoleVO { private String roleId; private String roleName; private LocalDateTime createTime;} @Datapublic class RoleDTO { private String roleId; private String roleName; private LocalDateTime createTime;}@Datapublic class RoomVO { private String roomId; private String buildingId; private String roomName; private String buildingName;}@Datapublic class RoomDTO { private String roomId; private String buildingId;}

There are many similar tools on the non-intrusion market, the more commonly used ones are

  • Spring BeanUtils (copyProperties)

  • CglibBeanCopier(copyProperties)

  • Apache BeanUtils (copyProperties)

  • Apache PropertyUtils (copyProperties)

  • Dozer

  • mapstruct

  • JSON serialization and deserialization

These tools not only need to introduce corresponding dependent jar packages, but also intrude into the code. They need to call the corresponding api method to perform conversion. Once the type is inconsistent and the field name changes slightly, you need to write additional java code to complete the field. The overall code is very ugly.

Example:

?

mapstruct

?

For the same code, you not only need to introduce dependencies and write the following conversion mapper, but also call the corresponding api (code intrusion verification) in the corresponding place. However, Simple Object Copy only needs to be generated with one click.

RoomName and buildingName that do not exist in RoomDTO require mapstruct to write additional methods, which are easy to ignore. There is no prompt for attributes that do not exist in the source entity. Be careful that the front end always asks why they are all null.

After the Simple Object Copy plug-in code is generated, empty methods are also generated for non-existing fields. Direct compilation prompts are added, which is not easy to ignore.

Requires handwritten code:

@Mapper(componentModel = "spring",uses = {RoleVOMapper.class,RoomVOMapper.class})public interface UserMapper { UserConverter INSTANCE = Mappers.getMapper(UserConverter.class); UserVO toUserVO(UserDTO userDTO);} @Mapper(componentModel = "spring")public interface RoleMapper { RoleVO toRoleVO(RoleDTO roleDTO);}@Mapper(componentModel = "spring")public interface RoomMapper { RoomVO toRoomVO(RoomDTO roomDTO);} public class Main { public static void main(String[] args) { UserDTO user = ; UserVO userVO = UserMapper.INSTANCE.toUserVO(user); userVO.getRoomVO().setRoomName("Lobby 1"); userVO.getRoomVO().setBuildingName ("Shangde Building"); }}

?

BeanUtils

?

Performance is slightly worse.

If complex objects are not supported, a lot of code still needs to be written. The code fields are not clear and difficult to understand, making it difficult for others to take over. RoomName and buildingName that do not exist in RoomDTO require BeanUtils to write additional methods, which are easy to ignore. There is no prompt for attributes that do not exist in the source entity. Be careful that the front end always asks why they are all null.

Requires handwritten code

@Datapublic 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 == null) { return null ; } UserVO result = new UserVO(); BeanUtils.copyProperties(item,result); List<RoleDTO> roleList = item.getRoleList(); if (roleList == null) { result.setRoleList(null); } 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 == null) { return null; } RoomVO result = new RoomVO(); BeanUtils.copyProperties(item,result); result.setRoomName(); result.setBuildingName(); return result; } public static RoleVO convertToRoleVO(RoleDTO item) { if (item == null) { return null; } RoleVO result = new RoleVO(); BeanUtils.copyProperties(item,result); return result; }}
Performance advantages

Compared with the above tool classes, either reflection, proxy, or serialization operations are used. Compared to the pure set method for conversion, the difference is not an order of magnitude. I won’t go into details this time.

Flexibility and compatibility

Plug-ins have great advantages compared to the above tools. I won’t go into details. Let’s compare them with the idea plug-in generateO2O that I used before.

bd04fab3473e7717dec8a6d22f4e2030.png

Here I recommend another plug-in that I commonly use: generateAllSetter, which is better when used together.

How to download?

Open idea plugins, go to market place and search: Simple Object Copy

38701039bea2a98b4ba2b36d006b1a66.png

1.2TSharing of useful learning materials for architects

2.10000 + TB resources, Alibaba cloud disk, awesome! !

3. Basically covers the summary of all core knowledge points of Spring

· END ·

Finally, follow the public account Internet Architect and reply in the background: 2T, you can get the Java series interview questions and answers I compiled, which is very complete.

If this article is helpful or inspiring to you, please scan the QR code above to pay attention. Your support is my biggest motivation to keep writing.

Please like, retweet and watch three times in one click