본문 바로가기

IT

MapStruct 사용 시 꼭 알아야 할 30가지 질문과 답변

728x90
반응형
728x170

안녕하세요! 오늘은 Java 개발자들이 객체 매핑을 위해 많이 사용하는 MapStruct에 대해 이야기해보려고 합니다. MapStruct를 처음 접하거나 사용하면서 궁금해할 만한 질문들을 한곳에 모아봤습니다. 재미있게 읽으시고, 개발에 도움이 되길 바랍니다!


1. MapStruct란 무엇인가요?

MapStruct는 Java 애플리케이션에서 객체 간의 매핑을 간편하게 해주는 애노테이션 기반 코드 생성 라이브러리입니다. 컴파일 타임에 타입 안전한 매핑 코드를 생성하여 성능과 생산성을 높여줍니다.

2. 왜 MapStruct를 사용해야 하나요?

  • 성능 향상: 런타임이 아닌 컴파일 타임에 코드를 생성하므로 성능 오버헤드가 없습니다.
  • 생산성 증대: 반복적인 매핑 코드를 자동으로 생성하여 개발 시간을 단축합니다.
  • 오류 감소: 타입 안전성을 보장하여 컴파일 시점에 오류를 발견할 수 있습니다.

3. MapStruct를 프로젝트에 어떻게 설정하나요?

빌드 도구에 따라 의존성을 추가하면 됩니다.

Maven 예시:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.0.Final</version>
</dependency>
<annotationProcessorPaths>
    <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.5.0.Final</version>
    </path>
</annotationProcessorPaths>

Gradle 예시:

implementation 'org.mapstruct:mapstruct:1.5.0.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.0.Final'

4. 기본적인 매퍼 인터페이스는 어떻게 작성하나요?

@Mapper
public interface UserMapper {
    UserDto toDto(User user);
}

컴파일 시 UserMapperImpl 구현체가 자동으로 생성됩니다.

5. 커스텀 매핑은 어떻게 하나요?

필드명이 다르거나 타입 변환이 필요할 때 @Mapping 애노테이션을 사용합니다.

@Mapper
public interface UserMapper {
    @Mapping(source = "name", target = "username")
    UserDto toDto(User user);
}

6. 컬렉션이나 배열은 매핑할 수 있나요?

네, 리스트나 배열 등 컬렉션 타입도 매핑 가능합니다.

List<UserDto> toDtoList(List<User> users);

7. Nested 객체는 어떻게 매핑하나요?

내부 객체도 자동으로 매핑되지만, 필요에 따라 별도의 매퍼를 정의할 수 있습니다.

@Mapper
public interface OrderMapper {
    OrderDto toDto(Order order);
}

8. 매핑을 무시하고 싶은 필드는 어떻게 처리하나요?

@Mapping 애노테이션의 ignore 속성을 사용합니다.

@Mapping(target = "password", ignore = true)

9. 매핑 시 기본값을 설정할 수 있나요?

defaultValue 속성을 통해 기본값을 지정할 수 있습니다.

@Mapping(target = "status", defaultValue = "ACTIVE")

10. 매핑 중 Null 처리는 어떻게 하나요?

nullValueMappingStrategy를 설정하여 Null 값을 처리할 수 있습니다.

@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)

11. MapStruct와 Lombok을 함께 사용할 수 있나요?

네, 가능합니다. 하지만 애노테이션 프로세서의 순서를 조정해야 합니다. Lombok이 먼저 처리되도록 설정하세요.

12. 조건부 매핑은 어떻게 구현하나요?

@Condition 애노테이션을 사용하여 조건부 매핑을 설정합니다.

@Condition
public boolean isNotEmpty(String value) {
    return value != null && !value.isEmpty();
}

13. 다중 소스 객체를 매핑할 수 있나요?

네, 여러 개의 소스를 매핑 메서드의 매개변수로 사용할 수 있습니다.

@Mapping(source = "user.name", target = "username")
@Mapping(source = "address.street", target = "street")
UserDto toDto(User user, Address address);

14. 매핑 메서드 간에 구성을 상속할 수 있나요?

@InheritConfiguration@InheritInverseConfiguration을 사용하여 매핑 구성을 상속합니다.

15. 빌더 패턴을 사용하는 객체도 매핑할 수 있나요?

네, @Builder 애노테이션을 사용하여 빌더 패턴을 지원합니다.

@Mapper
public interface UserMapper {
    @Mapping(target = "id", source = "userId")
    UserDto toDto(User user);

    @BeanMapping(builder = @Builder(disableBuilder = false))
    UserDto toDtoWithBuilder(User user);
}

16. MapStruct에서 예외 처리는 어떻게 하나요?

매핑 메서드에서 예외를 던질 수 있으며, 필요한 경우 throws를 선언합니다.

UserDto toDto(User user) throws CustomException;

17. 생성된 매핑 코드를 확인하려면 어떻게 하나요?

프로젝트의 target/generated-sources/annotations 디렉토리에서 생성된 코드를 확인할 수 있습니다.

18. MapStruct의 컴파일 오류는 어떻게 해결하나요?

컴파일 시 출력되는 오류 메시지를 참고하여 매핑 설정을 수정합니다. 타입 미스매치나 누락된 매핑이 없는지 확인하세요.

19. MapStruct 업데이트 시 주의할 점은 무엇인가요?

버전 업그레이드 시 호환성 문제가 발생할 수 있으므로, 릴리스 노트를 확인하고 필요한 코드를 수정합니다.

20. 기존 객체를 업데이트하는 매핑은 어떻게 하나요?

@MappingTarget을 사용하여 기존 객체를 매핑 결과로 업데이트할 수 있습니다.

void updateFromDto(UserDto dto, @MappingTarget User entity);

21. 매핑 중에 로그를 출력할 수 있나요?

MapStruct 자체적으로는 지원하지 않지만, @AfterMapping 또는 @BeforeMapping을 사용하여 로그를 추가할 수 있습니다.

22. 매핑 우선순위는 어떻게 결정되나요?

명시적인 매핑 설정이 자동 매핑보다 우선합니다.

23. Enum 타입은 어떻게 매핑하나요?

Enum은 이름이 동일하면 자동으로 매핑됩니다. 이름이 다를 경우 @Mapping을 사용합니다.

24. MapStruct에서 형 변환은 어떻게 하나요?

필요한 경우 @MappingqualifiedByName이나 qualifiedBy를 사용하여 커스텀 메서드를 지정합니다.

25. Cycle 문제가 발생하면 어떻게 해결하나요?

재귀적인 구조에서 무한 루프를 방지하기 위해 @Context를 사용하거나 매핑 깊이를 제한합니다.

26. 상속 구조의 객체는 어떻게 매핑하나요?

MapStruct는 상속을 지원하며, 부모 클래스의 필드도 자동으로 매핑됩니다.

27. 테스트 코드는 어떻게 작성하나요?

매핑 메서드를 호출하여 기대하는 결과가 나오는지 검증합니다.

@Test
public void testToDto() {
    User user = new User();
    user.setName("John");
    UserDto dto = userMapper.toDto(user);
    assertEquals("John", dto.getUsername());
}

28. MapStruct의 대안은 무엇인가요?

ModelMapper, Dozer 등이 있지만, MapStruct는 컴파일 타임 코드 생성으로 성능 이점이 있습니다.

29. 동적 매핑은 지원하나요?

MapStruct는 정적 매핑을 지향하므로, 동적 매핑은 지원하지 않습니다.

30. MapStruct를 사용하면서 주의할 점은 무엇인가요?

  • 컴파일 타임 오류 확인: 매핑 오류는 컴파일 시점에 확인하므로, 빌드 로그를 잘 확인하세요.
  • 의존성 관리: 애노테이션 프로세서와 라이브러리 버전이 일치해야 합니다.

여기까지 MapStruct를 사용하면서 자주 묻는 질문들을 정리해봤습니다. 도움이 되셨길 바라며, 즐거운 개발 되세요!

728x90
반응형
그리드형