dto la gi

Home

Java

Bạn đang xem: dto la gi

DTO là gì? Dùng DTO trong mỗi tình huống nào?

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