loose
이로운 개발하기
loose
전체 방문자
오늘
어제
  • 전체 (207)
    • ☕ Java (24)
    • 📘 Effective Java (9)
    • 🍃 Spring (48)
    • 📖 ORM (9)
    • ☸️ Kubernetes (13)
    • 🐧 Linux (5)
    • 🐋 Docker (5)
    • 🛠️ CI & CD (7)
    • 🕸️ Web (6)
    • 🔗 Distributed System (3)
    • 📜 Js (10)
    • 📈 Database (11)
    • 🗂️ Etc (34)
    • 🧑 Chitchat (11)
    • 📒 문학 (11)
    • 👜 개인 공부 창고 (1)

공지사항

반응형

최근 글

최근 댓글

loose

이로운 개발하기

🍃 Spring

ModelMapper, MapStruct 빠른 기초 사용법

2022. 10. 29. 02:23
반응형

ModelMapper와 MapStruct는 하나의 객체의 값을 다른 객체에 바인딩 시킬 때 쓰인다.

보통 Entity로 가져온 데이터를 Response DTO에 바인딩 시킬 때 쓰는 라이브러리다.

 

아래와 같은 Member Entity의 값을 DTO로 넘기는 예제를 만들어보겠다.

@Entity
@Getter @Setter
public class Member {

    @Id @GeneratedValue
    @Column
    private Long id;

    private String name;
}

라이브러리 안쓰고 사용하기

@Getter
public class MemberResponseDto {
    private String name
    private String author;

    public MemberResponseDto(Posts entity) {
        this.name = entity.getName();
    }
}

아래와 같이 DTO의 생성자를 호출해서 값을 바인딩한다.

 

Member member = new Member();
member.setName("loose");
MemberResponseDto memberResponseDto = new MemberResponseDto(member);
System.out.println(memResponseDto.getName("loose")); // loose 출력

 

Model Mapper 라이브러리 사용

 

gradle에 Model Mapper 라이브러리 추가

implementation 'org.modelmapper:modelmapper:2.4.2'

DTO에 Getter와 Setter를 필수로 넣어준다.

@Getter @Setter //필수
public class MemberResponseDto {
    private String name
    private String author;
}

아래와 같이 Dto에 바인딩 후 출력한다.

Member member = new Member();
member.setName("loose");

ModelMapper modelMapper = new ModelMapper();

MemberResponseDto memberResponseDto = modelMapper.map(member, MemberResponseDto.class);
System.out.println(memberResponseDto.getName()); //loose 출력

하지만 Model Mapper는 성능상의 이슈로 잘 쓰이지는 않는다고 한다.

 

MapStruct 라이브러리 사용

gradle에 MapStruct 라이브러리 추가

MapStruct도 Model Mapper처럼 getter와 setter를 필수로 사용한다.

그렇기 때문에 보통 Lombok을 같이 사용한다.

implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor "org.mapstruct:mapstruct-processor:1.4.2.Final"
    
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok-mapstruct-binding:0.2.0'

Mappers.getMapper 사용

Entity 값을 DTO에 바인딩 하기위해서 @Mapper가 붙은 Interface를 필수로 만들어야한다.

@Mapper
public interface SimpleSourceDestinationMapper {
    MemberDto sourceToDestination(Member source);
    Member destinationToSource(MemberDto destination);
}

만든 Interface를 Mappers.getMapper로 가져와서 아래와 같이 사용할 수 있다.

private SimpleSourceDestinationMapper mapper
        = Mappers.getMapper(SimpleSourceDestinationMapper.class);
@Test
public void test() throws Exception {
    Member member = new Member();
    member.setName("loose");
    MemberDto memberDto = mapper.sourceToDestination(member);

    System.out.println(memberDto.getName()); // loose 출력
}

의존성 주입 사용

@Mapper에(componentModel = "spring")를 적어주면 위처럼 Mappers.getMapper로 가져오지 않고 의존성 주입을 사용할 수 있다.

@Mapper(componentModel = "spring")
public interface SimpleSourceDestinationMapper {
    MemberDto sourceToDestination(Member source);
    Member destinationToSource(MemberDto destination);
}
@Autowired
MemberMapper mapper;
@Test
public void test() throws Exception {
    Member member = new Member();
    member.setName("loose");
    MemberDto memberDto = mapper.sourceToDestination(member);

    System.out.println(memberDto.getName()); // loose 출력
}

Mappers.getMapper 와 의존성 주입 이용하지 않고 변환하기

아래와 같이 인터페이스를 작성하면 의존성 주입을 하지 않고도 변환이 가능하다.

@Mapper(componentModel = "spring")
public interface MemberMapper {
    MemberMapper INSTANCE = Mappers.getMapper(MemberMapper.class);
    MemberDto to(Member member);
}
//Mappers.getMapper도 필요없고 의존성 주입도 필요 없다.
@Test
public void test() throws Exception {
    Member member = new Member();
    member.setName("loose");
    MemberDto memberDto = MemberMapper.INSTANCE.to(member);

    System.out.println(memberDto.getName()); // loose 출력
}

변환되어야 할 필드가 너무 많을 때 사용하면 좋은 라이브러리인 것은 확실하다.

그렇기에 DTO가 크지 않다면 소규모 프로젝트에서 굳이 쓸 이유가 없을 듯 하다.

728x90

'🍃 Spring' 카테고리의 다른 글

스프링부트 로그 찍는 법, 로그 파일 만드는 방법  (0) 2022.12.01
@Component와 Static 메소드 중 Utility Class는 어디에 만들까?  (0) 2022.11.13
@RequestBody, @ModelAttribute의 사용 이유와 목적, 활용  (0) 2022.10.23
Spring Boot로 만드는 Spring Security 로그인 구현 - JWT(2)  (6) 2022.10.18
Spring Boot로 만드는 Spring Security 로그인 구현 - Session(1)  (2) 2022.10.10
    '🍃 Spring' 카테고리의 다른 글
    • 스프링부트 로그 찍는 법, 로그 파일 만드는 방법
    • @Component와 Static 메소드 중 Utility Class는 어디에 만들까?
    • @RequestBody, @ModelAttribute의 사용 이유와 목적, 활용
    • Spring Boot로 만드는 Spring Security 로그인 구현 - JWT(2)
    loose
    loose
    불만하는 사람은 90명, 해결하는 사람은 9명, 리드하는 사람은 1명 음악과 낭만을 좋아합니다.
    hELLO. 티스토리 스킨을 소개합니다.
    제일 위로

    티스토리툴바