我通常在 DTO 中实现方法以将它们转换为实体。我这样做是因为我的目标是使实体的代码尽可能干净。但是,我收到的反馈表明实体接受 DTO 作为参数并创建实体更为自然。 我读了这篇文章如何将DTO转换为实体,但即使读了它我也不太理解。
DTO
public record MemberRegistRequestDto(
@NotBlank String oauthId,
@NotBlank String oauthPlatform,
@NotBlank String name,
@NotBlank String profileImg,
@NotBlank String nickname,
@NotNull int birth,
@NotBlank String gender,
@NotBlank String profession,
@NotBlank String signatureColor,
@NotBlank String contentType
) {
public Member of() {
return Member.builder()
.oauthId(oauthId)
.oauthPlatform(getOAuthProviderFromString(oauthPlatform))
.name(name)
.profileImg(profileImg)
.nickname(nickname)
.birth(birth)
.gender(gender)
.profession(profession)
.signatureColor(signatureColor)
.profileImg(profileImg)
.build();
}
...
}
实体
@Entity
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Table(indexes = @Index(name = "oauth_id", columnList = "oauthId", unique = true))
public class Member extends BaseTimeEntity implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String oauthId;
@Enumerated(EnumType.STRING)
private OAuthProvider oauthPlatform;
@Column(nullable = false)
private String name;
private String profileImg;
@Column(nullable = false)
private String nickname;
private Integer birth;
private String gender;
private String profession;
@Column(nullable = false)
private String signatureColor;
// 로그인 정보 식별 값, 프로필 사진, 필명, 이름, 성별, 생년월일, 이메일
@OneToMany(mappedBy = "member", cascade = CascadeType.ALL)
private List<Adate> adates;
...
}
将 Dto 转换为实体(服务层)
@Transactional
public void registMember(MemberRegistRequestDto memberRegistRequestDto) {
Member member = memberRegistRequestDto.of();
memberRepository.save(member);
}
建议实体接受 DTO 作为参数。
var member = Member.of(memberRegistRequestDto);
我读过很多 Stack Overflow 上的文章,但一直没能很好地理解它们。
我读过的 干净的编码器博客
将 DTO 转换为 DTO 类中的实体会在 DTO 和实体之间引入一定程度的依赖关系(增加耦合),因为 DTO 必须了解实体的内部结构。 Dto 应尽可能简单,并且映射应由有助于创建对象的单独映射器类在控制器中处理。
解决问题的一种方法是通过映射器类。
在 DTO 模式中,您拥有包含所有业务逻辑类的域模型和 DTO,它们是简单的 POJO,允许您在单点中仅公开所需的内容。这种模式具有许多优点,例如:减少到服务器的往返次数、最小化网络开销以及将域模型与表示层解耦。
但是,要将域模型的对象转换为 DTO,您应该使用映射器类。这种方法允许您将实体与 DTO 分离,因为实体没有(也不应该)了解 DTO 的内部实现,反之亦然。这种设计还遵循德米特法则(或最少知识原则),即类应该只知道它需要知道的内容。
在您的情况下,您应该拥有
MemberMapper
类,其中包含服务 public static MemberRegistRequestDto toMemberRegistRequestDto(Member)
,该服务从 MemberRegistRequestDto
实体返回 DTO Member
。
这是 Baeldung 的一篇文章,可以帮助您对问题有更多见解和示例 https://www.baeldung.com/java-dto-pattern