- 강사님에게 배웠던 방법대로 작성
- field name이 같은 것들 끼리 mapping이 이루어진다.
- 이외 방법은 하나씩 해보면서 함
- interface에서 default를 이용해서 수동 구현
- 알려준 방법만을 사용하고 다른 기능들을 사용하지 않음
- 다른 Mapper의 mapping 결과를 가져가다 쓸 수 없음
- field의 이름이 다를 때도 수동으로 Mapping을 함
- field의 다른 결과 값을 집어넣지 못함
- 수동으로 구현한 method가 많아서 DTO, Entity 변경에 취약함
-
Mapstruct 공식 문서를 참고하여 다음과 같은 방법을 찾음
- 다른 Mapper의 method를 가져다가 사용하는 방법 : @Mapper(uses = {AnotherMapper.class})
- 이름이 다른 field끼리의 Mapping : @Mapping(target = "member.memberId", source = "memberId")
- field에 다른 결과 값을 집어 넣기 : @Mapping(target = "answerCount", expression = "java(question.getAnswers().size())")
- 해당 사항들은 블로그에 정리 // 블로그 보완 필요해 보임
- 중복 코드 감소 (관련 코드 58% 감소)
- Mapstruct에서 제공하는 다양한 기능 사용
// 변경 전
@Mapper(componentModel = "spring")
public interface QuestionMapper {
default Question questionPostDtoToQuestion(QuestionDto.Post post){
Question question = new Question();
question.setTitle(post.getTitle());
question.setContent(post.getContent());
Member memberData = new Member();
memberData.setMemberId(post.getMemberId());
question.setMember(memberData);
return question;
}
Question questionPatchDtoToQuestion(QuestionDto.Patch patch);
default QuestionDto.Response questionToQuestionResponseDto(Question question){
Answer bestAnswer = question.getBestAnswer();
return new QuestionDto.Response(
question.getQuestionId(),
question.getTitle(),
question.getContent(),
question.getView(),
question.getVote(),
question.getCreatedAt(),
question.getModifiedAt(),
memberToMemberSubResponseDto(question.getMember()),
answersToAnswerResponseDtos(question.getAnswers()),
question.getAnswers().size(),
bestAnswer != null ? bestAnswer.getAnswerId() : null
);
};
default List<QuestionDto.SubResponse> questionsToQuestionSubResponseDtos(List<Question> question){
return question.stream()
.map(question1 -> questionToQuestionSubResponseDto(question1))
.collect(Collectors.toList());
}
default QuestionDto.SubResponse questionToQuestionSubResponseDto(Question question){
Answer bestAnswer = question.getBestAnswer();
return new QuestionDto.SubResponse(
question.getQuestionId(),
question.getTitle(),
question.getContent(),
question.getView(),
question.getVote(),
question.getCreatedAt(),
question.getModifiedAt(),
memberToMemberSubResponseDto(question.getMember()),
question.getAnswers().size(),
bestAnswer != null ? bestAnswer.getAnswerId() : null
);
}
MemberDto.SubResponse memberToMemberSubResponseDto(Member member);
List<AnswerDto.Response> answersToAnswerResponseDtos(List<Answer> answer);
}
// 변경 후
@Mapper(componentModel = "spring", uses = {MemberMapper.class, AnswerMapper.class})
public interface QuestionMapper {
@Mapping(target = "member.memberId", source = "memberId")
Question questionPostDtoToQuestion(QuestionDto.Post post);
Question questionPatchDtoToQuestion(QuestionDto.Patch patch);
@Mapping(target = "answerCount", expression = "java(question.getAnswers().size())")
@Mapping(target = "bestAnswerId",
expression = "java(question.getBestAnswer() != null ? question.getBestAnswer().getAnswerId() : null)")
QuestionDto.Response questionToQuestionResponseDto(Question question);
@Mapping(target = "answerCount", expression = "java(question.getAnswers().size())")
@Mapping(target = "bestAnswerId",
expression = "java(question.getBestAnswer() != null ? question.getBestAnswer().getAnswerId() : null)")
QuestionDto.SubResponse questionToQuestionSubResponseDto(Question question);
List<QuestionDto.SubResponse> questionsToQuestionSubResponseDtos(List<Question> question);
}