MapStruct로 다른 type을 매핑해보자

코딩하는범이·2020년 7월 21일
2
post-thumbnail

MapStruct란 클래스간 변환을 편하게 해주는 라이브러리입니다.
이 라이브러리를 사용하면 Builder를 사용해 값을 하나씩 넣어주지 않아도
자동으로 객체에 값을 주입시킬 수 있습니다.

아래는 MapStruct 공식 사이트 문서입니다.
(공식 사이트를 항상 보는 습관을 들입시다!!)
MapStruct Documentation

오늘은 Mapstruct로 다른 type을 매핑 하는게 주제이기 때문에
Mapstruct의 기초적인 사용법은 안다고 생각하고 진행하겠습니다.

사용하실 줄 모르신다면 꼭 위에 있는 공식 사이트를 참고해서 코드를 짜보세요!

이 MapStruct를 사용하다가 DTO의 타입과
Entity의 타입이 다른데 주입을 시켜야하는 상황이 발생했습니다.

문제의 코드입니다.
(코드를 쉽게 보기 위해서 몇개의 필드를 제거했습니다.)

Entity

@Entity
@Setter
@Getter
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @Column(columnDefinition="TEXT")
    private String contents;

    private boolean hasComment;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
    @Builder.Default
    private Set<Tag> tags;
}

DTO

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PostDTO {

    private Long blogId;
    private String title;
    private String contents;
    private boolean hasComment;
    private Set<String> tags;
}

mapper

@Mapper(componentModel = "spring")
public interface PostMapper {
    Post toMap(PostDTO postDTO);
}

여기서 저의 문제는 Set<String>을 mapper로 Set<Tag>
로 변경을 해야 하는것이였습니다.

먼저 Tag라는 클래스를 보겠습니다.

@Entity
@Setter
@Getter
public class Tag {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @ManyToOne
    private Post post;
}

Set의 String을 Set의 커스텀 객체인 Tag로 바꿔야 하는 것입니다.

그래서 바뀐 코드의 내용은 이렇습니다.

mapper

@Mapper(componentModel = "spring")
public interface PostMapper {
    default Post toMap(PostDTO postDTO) {
        Post post = new Post();
        post.setTitle(postDTO.getTitle());
        post.setContents(postDTO.getContents());
        post.setHasComment(postDTO.isHasComment());
        post.setActivation(postDTO.getActivation());
        HashSet<Tag> hs = new HashSet<>();
        if(postDTO.getTags()!=null) {
            postDTO.getTags().stream().forEach(t -> {
                Tag tag = new Tag();
                tag.setName(t);
                tag.setPost(post);
                hs.add(tag);
            });
        }
        post.setTags(hs);
        return post;
}

직접 DTO의 값을 Post객체로 세팅해줍니다.
주의) mapper를 사용할때에 null 값이 존재하면 안됩니다.

이것과 관련해서 MapStruct에서는 전략 방식을 설정할 수있는 기능을 지원합니다.
NullValueCheckStrategy
NullValueMappingStrategy
Nullvaluepropertymappingstrategy

저장해서 데이터 베이스에 있는 결과 값을 보면

잘 들어간것을 확인 할 수 있습니다.

profile
기록 그리고 기억

0개의 댓글