# ModelMapper 소개
ModelMapper는 Java 객체 간의 매핑을 쉽게 해주는 라이브러리입니다. 복잡한 객체 변환 코드를 작성할 필요 없이 객체의 속성들을 자동으로 매핑해주어 개발 시간을 단축하고 코드의 가독성을 높여줍니다.
## ModelMapper의 주요 특징
- **타입 안전성**: 컴파일 시점에서 타입 오류를 확인할 수 있습니다.
- **자동 매핑**: 이름과 타입이 일치하는 속성들을 자동으로 매핑합니다.
- **커스텀 매핑**: 복잡한 매핑 로직을 위한 커스텀 컨버터 지원
- **깊은 매핑**: 중첩된 객체 구조도 쉽게 매핑 가능
- **설정 유연성**: 다양한 매핑 전략 및 설정 제공
## ModelMapper 사용 방법
### 1. 의존성 추가
Maven을 사용한다면 pom.xml에 다음 의존성을 추가합니다:
```xml
org.modelmapper
modelmapper
3.0.0
```
Gradle을 사용한다면 build.gradle에 다음을 추가합니다:
```groovy
implementation 'org.modelmapper:modelmapper:3.0.0'
```
### 2. 기본 사용법
```java
// ModelMapper 인스턴스 생성
ModelMapper modelMapper = new ModelMapper();
// 소스 객체에서 대상 객체로 매핑
DestinationType destination = modelMapper.map(source, DestinationType.class);
```
### 3. 실제 사용 예시
다음은 사용자 정보를 담은 엔티티와 DTO 간의 변환 예시입니다:
```java
// 엔티티 클래스
public class User {
private Long id;
private String email;
private String password;
private String firstName;
private String lastName;
private Address address;
// 생성자, getter, setter 생략
}
public class Address {
private String street;
private String city;
private String country;
private String zipCode;
// 생성자, getter, setter 생략
}
// DTO 클래스
public class UserDTO {
private Long id;
private String email;
private String fullName;
private AddressDTO address;
// 생성자, getter, setter 생략
}
public class AddressDTO {
private String street;
private String city;
private String country;
private String zipCode;
// 생성자, getter, setter 생략
}
// 매핑 예시
public class UserService {
private final ModelMapper modelMapper;
public UserService() {
this.modelMapper = new ModelMapper();
// firstName과 lastName을 fullName으로 매핑하는 커스텀 설정
modelMapper.createTypeMap(User.class, UserDTO.class)
.addMappings(mapper -> {
mapper.map(src -> src.getFirstName() + " " + src.getLastName(),
UserDTO::setFullName);
});
}
public UserDTO convertToDTO(User user) {
return modelMapper.map(user, UserDTO.class);
}
public User convertToEntity(UserDTO userDTO) {
return modelMapper.map(userDTO, User.class);
}
}
```
### 4. 고급 매핑 기능
#### 커스텀 매핑 설정
```java
// 속성 이름이 다른 경우 명시적 매핑
modelMapper.createTypeMap(Source.class, Destination.class)
.addMapping(Source::getSourceProperty, Destination::setTargetProperty);
// 조건부 매핑
modelMapper.getConfiguration().setPropertyCondition(context -> {
// 조건에 따라 true/false 반환
return context.getSource() != null;
});
// 타입 변환 매핑
Converter stringToDateConverter =
ctx -> ctx.getSource() == null ? null : new SimpleDateFormat("yyyy-MM-dd").parse(ctx.getSource());
modelMapper.createTypeMap(Source.class, Destination.class)
.addMappings(mapper -> mapper.using(stringToDateConverter)
.map(Source::getDateAsString, Destination::setDate));
```
#### 매핑 전략 설정
```java
// 필드 매핑 전략 (필드 이름 기준 매핑)
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
// 접근 방식 설정 (필드 직접 접근)
modelMapper.getConfiguration().setFieldAccessLevel(AccessLevel.PRIVATE);
modelMapper.getConfiguration().setFieldMatchingEnabled(true);
```
### 5. 컬렉션 매핑
```java
// List 매핑
List userDTOs = users.stream()
.map(user -> modelMapper.map(user, UserDTO.class))
.collect(Collectors.toList());
// Type Token 사용하여 컬렉션 매핑
Type listType = new TypeToken>() {}.getType();
List userDTOs = modelMapper.map(users, listType);
```
## 실제 사용 사례
Spring Boot 애플리케이션에서 ModelMapper를 빈으로 등록하여 사용하는 예시:
```java
@Configuration
public class ApplicationConfig {
@Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
// 엄격한 매핑 전략 설정
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT)
.setSkipNullEnabled(true)
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PRIVATE);
return modelMapper;
}
}
@Service
public class ProductService {
private final ProductRepository productRepository;
private final ModelMapper modelMapper;
@Autowired
public ProductService(ProductRepository productRepository, ModelMapper modelMapper) {
this.productRepository = productRepository;
this.modelMapper = modelMapper;
}
public ProductDTO getProduct(Long id) {
Product product = productRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("Product not found"));
return modelMapper.map(product, ProductDTO.class);
}
public List getAllProducts() {
List products = productRepository.findAll();
return products.stream()
.map(product -> modelMapper.map(product, ProductDTO.class))
.collect(Collectors.toList());
}
}
```
## 결론
ModelMapper는 Java 애플리케이션에서 객체 간 매핑을 간소화하는 강력한 도구입니다. 자동 매핑 기능으로 반복적인 코드를 줄이고, 커스텀 매핑 설정으로 복잡한 변환 로직도 깔끔하게 처리할 수 있습니다. 특히 엔티티와 DTO 간의 변환이 많은 웹 애플리케이션에서 유용하게 활용할 수 있습니다.