# 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 간의 변환이 많은 웹 애플리케이션에서 유용하게 활용할 수 있습니다.