Deft September 12, 2021
DTO là gì?
DTO hoặc tên thường gọi vừa đủ là Data Tranfer Object là một trong những design pattern lượt trước tiên được reviews vị Martin Fowler vô cuốn sách EAA. Mục đích dùng chủ yếu của DTO này là hạn chế số lượt gọi những method trong số những tiến bộ trình xử lý.
Giảm số lượt gọi những method trong số những tiến bộ trình xử lý? chúng ta đem thấy khó khăn hiểu không? tôi đã rất rất sợ hãi Khi gọi định nghĩa này lượt trước tiên, song hãy nhìn qua một trường hợp sau.
Giả sử tất cả chúng ta đang được trở nên tân tiến một phần mềm trang web frontend, cần thiết thao tác với cùng một khối hệ thống backend REST API. Mỗi lượt gọi cho tới API nhằm xử lý tài liệu và nhận về thành quả tiếp tục tốn thật nhiều thời hạn vậy nên tất cả chúng ta cần thiết giới hạn tối phần đông lượt gọi cho tới API và làm thế nào nhằm từng lượt gọi tiếp tục xử lý được không ít yếu tố rộng lớn. Để thực hiện được điều này thì giờ trên đây những API cần thiết nhận nhiều thông số nguồn vào (parameters) rộng lớn nhằm xử lý nhiều việc làm vô một lượt.
Nếu như trước đó trên đây chỉ xử lý một việc làm A thôi thì API chỉ việc nhận 2 thông số X1,X2, tuy nhiên giờ nó được đòi hỏi cần xử lý tăng việc B nữa thì đem người sử dụng 4 thâm nám số X1, X2, X3, X4. Việc dùng rất nhiều thông số nguồn vào sẽ gây nên trở ngại mang đến việc thiết kế ở cả hai phía frontend và backend. Hơn nữa API giờ đó cũng cần trả nhiều loại tài liệu rộng lớn cho 1 request, điều này tiếp tục rất rất trở ngại mang đến Java Khi nó chỉ được chấp nhận trả về một Object độc nhất đem loại rõ ràng.
Giải pháp ở trên đây đó là khởi tạo nên một DTO object chứa chấp toàn bộ những tài liệu vô một lượt gọi cho tới API. Nó rất cần phải được serializable trước lúc được truyền qua chuyện connection và deserializable nhằm nhận lại DTO thuở đầu được gửi kể từ phía mặt mũi ê.
Domain model và DTO
Chúng tớ cần thiết phân biệt thân thiện Domain model và DTO nhằm rời lầm lẫn. Domain model là những Entity class dùng làm ánh xạ một table vô database còn DTO là một trong những object phối hợp nhiều thông số trở thành một bịa vô một DTO class.
Sử dụng DTO thế nào?
DTO là một trong những cấu tạo tài liệu phẳng phiu và ko chứa chấp business logic trong ê chỉ dùng làm tàng trữ tài liệu, những method được chấp nhận cập tài liệu và dùng vô quy trình serialization or deserialization. Dữ liệu được ánh xạ kể từ tên miền model sang trọng DTO và ngược lại trải qua một bộ phận gọi là Mapper được bịa vô presentation hoặc facade layer.
Để thực hiện rõ rệt rộng lớn cơ hội dùng DTO thì tất cả chúng ta tiếp tục thực hiện một API giản dị dùng Spring Boot. Các các bạn Note tại phần này tôi chỉ thể hiện một trong những đoạn code quan trọng nhằm thực hiện rõ rệt việc dùng DTO. Còn nhằm chạy được một phần mềm hoàn hảo thì những chúng ta có thể kéo xuống cuối bài bác sẽ sở hữu được liên kết mã mối cung cấp vừa đủ.
Domain model
Trước tiên, tất cả chúng ta sẽ sở hữu được 2 tên miền class là User và Role được khái niệm như sau
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String password; @ManyToMany private List<Role> roles; }
@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @ManyToMany(mappedBy = "roles") public List<User> users; }
Note: User và Role đem quan hệ Many-To-Many.
Xem thêm: u30 là gì
DTO class
Tiếp theo đòi tất cả chúng ta sẽ sở hữu được 3 DTO class bao gồm UserDTO, RoleDTO và UserCreationDTO. Trong số đó UserDTO và RoleDTO dùng làm ánh xạ User và Role Khi trả tài liệu về mang đến client còn UserCreationDTO dùng làm thêm 1 User mới mẻ vì thế khởi tạo nên User tất cả chúng ta ko chỉ việc những thông cơ phiên bản của chính nó như name, password mà còn phải cần thiết một list Role được ấn toan mang đến User.
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class UserDTO implements Serializable { private String name; private List<RoleDTO> roles; }
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class RoleDTO implements Serializable { private Long id; private String name; }
@Getter @Setter @NoArgsConstructor @AllArgsConstructor public class UserCreationDTO implements Serializable { private String name; private String password; private List<Long> roleIds; }
Mapper
Như đang được nhắc phía trên thì việc quy đổi hỗ tương thân thiện DTO và Domain model cần phải có một tấm trung lừa lọc ở trên đây bản thân người sử dụng Mapper.
Đầu tiên là UserMapper được chấp nhận quy đổi UserCreationDTO sang trọng User và kể từ User sang trọng UserDTO.
public class UserMapper { private static UserMapper INSTANCE; public static UserMapper getInstance() { if (INSTANCE == null) { INSTANCE = new UserMapper(); } return INSTANCE; } public User toEntity(UserCreationDTO dto) { User user = new User(); user.setName(dto.getName()); user.setPassword(dto.getPassword()); return user; } public UserDTO toDTO(User user) { UserDTO dto = new UserDTO(); dto.setName(user.getName()); dto.setRoles(user.getRoles().stream() .map(role -> RoleMapper.getInstance().toDTO(role)) .collect(Collectors.toList())); return dto; } }
Tiếp theo đòi là RoleMapper chứa chấp 2 method cơ phiên bản nhất dùng làm quy đổi hỗ tương thân thiện tên miền và dto.
public class RoleMapper { private static RoleMapper INSTANCE; public static RoleMapper getInstance() { if (INSTANCE == null) { INSTANCE = new RoleMapper(); } return INSTANCE; } public Role toEntity(RoleDTO roleDTO) { Role role = new Role(); role.setName(roleDTO.getName()); return role; } public RoleDTO toDTO(Role role) { RoleDTO dto = new RoleDTO(); dto.setName(role.getName()); dto.setId(role.getId()); return dto; } }
Service
Ở phần này tất cả chúng ta tiếp tục quan hoài cho tới UserService dùng làm khởi tạo nên User mới mẻ. Tại trên đây tất cả chúng ta tiếp tục nên dùng cho tới Mapper nhằm quy đổi kể từ DTO sang trọng User. Tiến hành lưu xuống database và lại người sử dụng Mapper nhằm quy đổi User object đã và đang được lưu xuống database sang trọng DTO và trả về mang đến client.
@Service @Transactional(rollbackFor = Throwable.class) public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Autowired private RoleRepository roleRepository; @Override public UserDTO create(UserCreationDTO dto) { User user = UserMapper.getInstance().toEntity(dto); List<Role> roles = roleRepository.findAllById(dto.getRoleIds()); user.setRoles(roles); return UserMapper.getInstance().toDTO(userRepository.save(user)); } @Override public List<UserDTO> findAll() { return userRepository.findAll().stream() .map(user -> UserMapper.getInstance().toDTO(user)) .collect(Collectors.toList()); } }
Như vậy những chúng ta có thể thấy tầm quan trọng của DTO vô tình huống này, UserCreationDTO đã và đang được dùng làm gói gọn toàn bộ những vấn đề quan trọng như vấn đề cơ phiên bản của một User và những Role được gán mang đến nó.
Controller
Tầng này tiếp tục nhận request kể từ client và fake xuống mang đến tầng Service xử lý nên những chúng ta có thể xem thêm qua
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @PostMapping public UserDTO create(@RequestBody UserCreationDTO dto) { return userService.create(dto); } @GetMapping public List<UserDTO> findAll() { return userService.findAll(); } }
@RestController @RequestMapping("/role") public class RoleController { @Autowired private RoleService roleService; @PostMapping public RoleDTO create(@RequestBody RoleDTO dto) { return roleService.create(dto); } }
Để chạy demo thì chúng ta cần thiết tuân theo công việc sau:
- Khởi tạo nên một trong những Role, ghi lại những Role ID vô response trả về (RoleIDs)
- Khởi tạo nên User với những vấn đề quan trọng và RoleIDs đã và đang được lưu ở bước 1
Khởi tạo nên User request hình mẫu như sau
curl --location --request GET 'http://localhost:8080/user' \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "deft", "password": "123456", "roleIds": [ 1 ] }'
Kết trái khoáy trả về tiếp tục như sau
[ { "name": "deft", "roles": [ { "id": 1, "name": "admin" } ] } ]
Tóm lược
Hy vọng qua chuyện trên đây những các bạn sẽ làm rõ rộng lớn về DTO pattern, bản thân tin cẩn rằng nhiều bạn đều dùng nó hằng ngày khi tham gia học và trở nên tân tiến những phần mềm API.
Link mã nguồn: dto-pattern
Xem thêm: nong nat dien vien thai lan
Nguồn tham lam khảo
https://martinfowler.com/eaaCatalog/dataTransferObject.html
https://www.baeldung.com/java-dto-pattern
Bình luận