Spring Boot中的DTO转换器模式

问题描述 投票:4回答:1

主要问题是如何在不破坏SOLID原则的情况下将DTO转换为实体和实体到Dtos。 例如,我们有这样的json:

{ id: 1,
  name: "user", 
  role: "manager" 
} 

DTO是:

public class UserDto {
 private Long id;
 private String name;
 private String roleName;
}

实体是:

public class UserEntity {
  private Long id;
  private String name;
  private Role role
} 
public class RoleEntity {
  private Long id;
  private String roleName;
}

还有有用的qazxsw poi。

但在他们的例子中,没有OneToMany关系。为了创建UserEntity,我需要使用dao层(服务层)通过roleName获取角色。我可以将UserRepository(或UserService)注入到对话器中。因为似乎转换器组件会破坏Java 8 DTO conveter pattern,它必须只转换,不得知道服务或存储库。

转换器示例:

SRP

在对流类中使用存储库是否好?或者我应该创建另一个负责从DTO(如UserFactory)创建实体的服务/组件?

java spring-boot design-patterns entity dto
1个回答
2
投票

如果您有服务层,则使用它进行转换或将任务委派给转换器会更有意义。 理想情况下,转换器应该只是转换器:映射器对象,而不是服务。 现在,如果逻辑不是太复杂并且转换器不可重用,您可以将服务处理与映射处理混合在一起,在这种情况下,您可以用@Component public class UserConverterImpl implements UserConverter<UserEntity, UserDto> { @Autowired private RoleRepository roleRepository; @Override public UserEntity createFrom(final UserDto dto) { UserEntity userEntity = new UserEntity(); Role role = roleRepository.findByRoleName(dto.getRoleName()); userEntity.setName(dto.getName()); userEntity.setRole(role); return userEntity; } .... 替换Converter前缀。

如果只有服务与存储库通信,它看起来也会更好。 否则层变得模糊,设计混乱:我们不知道谁再调用谁。

我会用这种方式做事:

Service

或者自己执行转换的服务(转换不是太复杂而且不可重用):

controller -> service -> converter 
                      -> repository

说实话,我讨厌DTO,因为这些只是数据重复。 我只介绍它们,因为客户要求的信息与实体表示不同,并且使得自定义类(在这种情况下不是重复的)更加清晰。

© www.soinside.com 2019 - 2024. All rights reserved.