Webserver 개발할 때 Database 나 Redis 등은 필수로 사용하게 된다. 이 때 API로 들어오는 데이터(DTO)를 Database에 저장되는 실제 Model로 복사하는 경우가 매번 발생하게 된다. 이때마다 chain이나 별도 function을 만들어서 복사를 할 수 없다. 왜냐하면 반복해서 넣어야 하는 동일한 코드가 너무 많기 때문이다.
이를 해결하기 위해서 ModelMapper를 사용한다. ObjectMapping을 쉽게 해주는 Library라고 보면 된다.
Applications often consist of similar but different object models, where the data in two models may be similar but the structure and concerns of the models are different. Object mapping makes it easy to convert one model to another, allowing separate models to remain segregated.
ModelMapper의 목적은 아래와 같다.
The goal of ModelMapper is to make object mapping easy, by automatically determining how one object model maps to another, based on conventions, in the same way that a human would - while providing a simple, refactoring-safe API for handling specific use cases.
Object mapping을 자동으로 이름이나 자료형을 가지고 판단하여 수행을 해준다. 반복된 코드를 줄여주기 때문에 효율적이고 휴먼에러는 줄여주는 역할도 한다고 하겠다.
Dependency 추가
ModelMapper를 사용하기 위해서는 우선 Dependecy를 추가한다. 이 글에서는 2.4.4 버전을 사용한다.
글을 쓰는 시점에서 최신 버전은 3.0.0 이다.
<properties>
<modelMapper.version>2.4.4</modelMapper.version>
</properties>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${modelMapper.version}</version>
</dependency>
ModelMapper Configuration 추가
Default option으로 사용해도 큰 문제는 없지만, 난 MatchStrategies 를 Strict 하게 하도록 하였고, Null value가 Object에 있어도 Mapping이 되도록 설정하였다.
@Configuration
public class ModelMapperConfig {
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT).setSkipNullEnabled(true);
return modelMapper;
}
}
Usage
사용방법은 간단하다. 아래의 예제는 ModelMapper object를 사용하였는데 위 설정으로 Bean에 등록을 하였으니 Dependecy Injection 으로 사용해도 된다.
Order & OrderDTO
class Order {
Customer customer;
Address billingAddress;
}
class Customer {
Name name;
}
class Name {
String firstName;
String lastName;
}
class Address {
String street;
String city;
}
class OrderDTO {
String customerFirstName;
String customerLastName;
String billingStreet;
String billingCity;
}
ModelMapper modelMapper = new ModelMapper();
OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class);
위와 같이 2개의 Model이 있고 Order model로 생성된 order object를 사용하여 OrderDTO object를 생성하는 코드이다.
놀라운 점은 하위 Object의 variable까지 Mapping 시킨다는 점이다.
앞으로의 코드에서 많이 사용되는 부분이라 우선 정리하였다.