infinity : 무한한 성장가능성
MapStruct 에 대해 알아보자 본문
ModelMapper 에 대해 알아보자
modelMapper을 알아보게 된 배경에 대해 설명하자면 어느 날 주말에 갑자기 잘 돌아가던 배치에서 실패메시지가 왔다.해당 부분에 변경사항이 없을 텐데 왜 실패가 되었지? 싶어 로그를 확인해 보
infinitecoding.tistory.com
MapStruct에 대해 알아보는 이유는 윗글에 나와있습니다.
이 글을 읽전에 위 글을 읽고 오는 것을 추천드립니다.
🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️MapStruct 알아보기 시작합니다. 🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️🏃♀️
MapStruct 란?
Java 기반의 매핑 프레임워크로 객체 간의 매필을 간단하고 성능 좋게 처리할 수 있다.
Spring Framework 와 함께 사용하면 편리하다.
MapStruct 사용법
1. 의존성 추가
maven
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version> <!-- 최신 버전 확인 -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
<scope>provided</scope>
</dependency>
gradle
implementation 'org.mapstruct:mapstruct:1.5.3.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final'
2. 매핑 대상 클래스 생성
public class UserDto {
private String name;
private int age;
}
public class UserEntity {
private String name;
private int age;
public UserEntity(String name, int age) {
this.name = name;
this.age = age;
}
}
(* 위 dto 와 entity 클래스는 모두 getter와 setter 메서드가 정의되어있어야 합니다.)
3. 매퍼 생성
package com.example.mapper;
import com.example.dto.UserDto;
import com.example.entity.UserEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDto toDto(UserEntity entity);
UserEntity toEntity(UserDto dto);
}
매퍼를 생성하는 코드를 살펴보자
Mpaaers.getMapper(UserMapper.class)
위 코드를 통해 MapStruct 가 컴파일 시점에 UserMapper 인터페이스를 기반으로 구현체 클래스를 생성한다.
따라서 위 코드를 호출하면 UserMapper 의 구현체의 싱글턴 인스턴스를 반환하게 됩니다.
INSTANCE
매퍼 객체를 싱글턴으로 사용하도록 정의한 필드
인터페이스에 필드를 선언하면 해당 필드는 암묵적으로 public static final로 선언됨
toDto & toEntity 메서드
toDto & toentity 메서드는 관례적으로 사용하는 메서드 이름으로 다른이름으로 사용해도 무방합니다.
입력타입과 반환타입을 Mapstruct 가 확인해 그에 맞는 구현체를 자동으로 생성해줍니다.
@Mapper 어노테이션
해당 어노테이션은 MapStruct 에게 해당 인터페이스가 매퍼 인터페이스임을 알려줍니다.
주요 속성
속성 | 설명 |
componentModel | 생성된 매퍼를 의존성주입(DI) 컨테이너에 등록하는 방법 (기본값은 default) |
uses | 다른 매퍼나 헬퍼 클래스를 참조할 때 사용 |
unmappedTargetPolicy | 매핑되지 않은 필드에 대한 정책 설정 (IGNORE, WARN, ERROR) |
사용해보기
package com.example.mapstruct;
import com.example.dto.UserDto;
import com.example.entity.UserEntity;
import com.example.mapper.UserMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MapstructApplication {
public static void main(String[] args) {
UserEntity userEntity = new UserEntity("John", 25);
//Entity -> Dto
UserDto userDto = UserMapper.INSTANCE.toDto(userEntity);
}
}
구현체도 자동으로 생성해 주고, 매우 간편하게 사용가능한 것을 볼 수 있습니다.
위에서 Spring Framework와 함께 사용하면 편리하다고 했었는데 어떻게 스프링과 통합하여 사용할 수 있는지 알아보겠습니다.
Spring과 통합하기
@Mapper을 spring과 통합하려면 componentModel = "spring"으로 설정하면 됩니다.
package com.example.mapper;
import com.example.dto.UserDto;
import com.example.entity.UserEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring")
public interface UserMapper {
UserDto toDto(UserEntity entity);
UserEntity toEntity(UserDto dto);
}
이렇게 설정하면 MapStruct 가 생성한 구현체가 Spring Bean으로 등록되어 의존성 주입으로 사용할 수 있게 됩니다.
package com.example.service;
import com.example.dto.UserDto;
import com.example.entity.UserEntity;
import com.example.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
public UserDto convertToDto(UserEntity entity) {
return userMapper.toDto(entity);
}
}
위 코드처럼 빈으로 등록되어 있기 때문에 의존성 주입으로 다른 서비스나, 컨트롤러단에서 쉽게 사용가능합니다.
간단하게 MapStruct를 사용하는 방법에 대해 알아보았습니다.
맨 처음 MapStruct 를 알게 된 이유가 ModelMapper이었기 때문에 두 개의 차이를 비교해 보면서 이 글을 마치도록 하겠습니다.
ModelMapper와 ModelStruct 비교
구분 | ModelMapper | MapStruct |
매핑방식 | 런타임(Reflection 기반) | 컴파일 시점(코드 생성기반) |
성능 | 상대적으로 느림 (매번 동적으로 매핑필드를 계산하기 때문) | 매우 빠름 ( 사전에 컴파일된 매핑 코드를 사용) |
구현방식 | 런타임에 동적으로 매핑 코드 생성 | 컴파일 시점에 매핑 코드를 생성 |
코드 가독성 | 매핑 코드가 자동화되어 간결하지만 디버깅이 어려움 | 매핑 코드가 명시적으로 생성되어 가독성 및 디버깅이 용이함 |
Spring 통합 | 축라 설정 없이 바로 사용가능 | @Mapper(componentModel = "spring") |
커스텀 매핑 | 커스텀 매핑이 비교적 복잡 | 애노테이션과 메서드로 간단히 커스텀매핑 가능 |
글에 잘못된 부분 혹은 개선해야할 점이 있으면 편하게 댓글 남겨주세요.
'Develop > 💜Java' 카테고리의 다른 글
ModelMapper 에 대해 알아보자 (0) | 2025.01.05 |
---|---|
자바 제네릭 완전정복 (2) (0) | 2024.02.18 |
자바 제네릭 완전정복 (1) (1) | 2024.01.21 |