DTO 간 복사
Spring에서 DTO 간 변수를 복사하는 경우, 주로 BeanUtils.copyProperties 메소드를 사용하거나 ModelMapper 라이브러리를 활용할 수 있습니다. 아래에 두 방법을 사용하는 예시를 제시하겠습니다.
1. BeanUtils 사용하기
BeanUtils.copyProperties 메소드는 스프링 프레임워크에 포함된 유틸리티 메소드로서, 한 객체의 프로퍼티 값을 다른 객체로 복사하는 데 사용됩니다. 이 방법은 추가적인 라이브러리를 필요로 하지 않으며, Spring Framework에 기본적으로 포함되어 있습니다.
import org.springframework.beans.BeanUtils;
// Source DTO
public class SourceDto {
private String name;
private int age;
// getters and setters
}
// Target DTO
public class TargetDto {
private String name;
private int age;
// getters and setters
}
SourceDto source = new SourceDto();
// source 객체 초기화
TargetDto target = new TargetDto();
BeanUtils.copyProperties(source, target);
2. ModelMapper 사용하기
ModelMapper는 더 복잡한 매핑이 필요할 때 유용하며, 객체 간의 데이터 매핑을 보다 세밀하게 제어할 수 있습니다. 이 라이브러리는 별도로 추가해야 합니다. ModelMapper를 사용하면 복잡한 매핑 규칙도 쉽게 정의할 수 있습니다.
<!-- pom.xml -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.8</version>
</dependency>
import org.modelmapper.ModelMapper;
// Source DTO
public class SourceDto {
private String name;
private int age;
// getters and setters
}
// Target DTO
public class TargetDto {
private String name;
private int age;
// getters and setters
}
ModelMapper modelMapper = new ModelMapper();
SourceDto source = new SourceDto();
// source 객체 초기화
TargetDto target = modelMapper.map(source, TargetDto.class);
ModelMapper는 좀 더 복잡한 변환 작업에 유리하며, 자동 매핑 외에도 맞춤 매핑 전략을 정의할 수 있습니다. BeanUtils에 비해 세밀한 제어가 가능하지만, 성능면에서는 BeanUtils가 더 빠를 수 있습니다. 따라서 상황에 맞게 선택하여 사용하시면 됩니다.
3. ModelMapper 커스텀 하는 예시
ModelMapper는 복잡한 변환 작업에 유리한 여러 가지 이유가 있는데, 그 중 하나는 객체 간의 필드 이름이 다르거나, 변환 로직이 필요할 때 보다 유연하게 대응할 수 있다는 점입니다. 예를 들어, 한 객체의 필드를 다른 객체의 여러 필드로 나누거나, 반대로 여러 필드를 하나로 합치는 등의 작업을 ModelMapper를 사용하여 쉽게 처리할 수 있습니다.
아래 예시에서는 ModelMapper를 사용하여 서로 다른 필드 이름을 매핑하고, 특정 필드에 대해 커스텀 변환 로직을 적용하는 방법을 보여줍니다.
3-1. Source DTO
public class SourceDto {
private String fullName; // TargetDto에서는 firstName과 lastName으로 나누어져 있음
private String email;
private String joinDate; // String 형식, TargetDto에서는 LocalDate 형식으로 변환 필요
// getters and setters
}
3-2. Target DTO
public class TargetDto {
private String firstName;
private String lastName;
private String email;
private LocalDate joinDate; // SourceDto에서는 String 형식, 여기서는 LocalDate로 변환
// getters and setters
}
3-3. ModelMapper 설정 및 사용
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.modelmapper.Converter;
import org.modelmapper.spi.MappingContext;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
ModelMapper modelMapper = new ModelMapper();
// fullName을 firstName과 lastName으로 나누는 커스텀 매핑
modelMapper.addMappings(new PropertyMap<SourceDto, TargetDto>() {
@Override
protected void configure() {
map().setEmail(source.getEmail());
using((Converter<String, String>) context -> context.getSource().split(" ")[0]).map(source.getFullName(), destination.getFirstName());
using((Converter<String, String>) context -> context.getSource().split(" ").length > 1 ? context.getSource().split(" ")[1] : null).map(source.getFullName(), destination.getLastName());
// joinDate 변환
using(new Converter<String, LocalDate>() {
@Override
public LocalDate convert(MappingContext<String, LocalDate> context) {
return LocalDate.parse(context.getSource(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
}
}).map(source.getJoinDate(), destination.getJoinDate());
}
});
SourceDto source = new SourceDto();
// source 객체 초기화
TargetDto target = modelMapper.map(source, TargetDto.class);
이 예시에서는 ModelMapper의 addMappings 메소드를 사용하여 커스텀 매핑을 정의했습니다. fullName을 firstName과 lastName으로 나누는 로직과 joinDate를 String에서 LocalDate로 변환하는 로직을 구현했습니다. 이처럼 ModelMapper는 필드 이름이 다르거나, 특정 필드에 대한 변환 로직이 필요할 때 유연하게 대응할 수 있는 강력한 도구입니다.
'Back-end > Spring' 카테고리의 다른 글
[Spring] @RestControllerAdvice 사용해서 Controller 예외처리 (1) | 2024.02.09 |
---|---|
[Spring] @SuperBuilder 의 특징과 간단한 예제 (0) | 2024.02.09 |
[Spring] 시큐리티 예외 처리와 사용자 인증 (시큐리티6 이상) (1) | 2024.01.30 |
[Spring] Security 6 버전 인메모리 사용자 설정 간단한 예제 (0) | 2024.01.30 |
[Swagger] Spring 3.0 이상 버전에서 스웨거 적용하는 방법 (0) | 2024.01.29 |