modelmapper는 런타임시점에 리플렉션이 발생하므로 성능 저하가 매우 심함
컴파일 시점에 코드가 생성되는 mapstruct 사용하는 것을 권장
// https://mvnrepository.com/artifact/org.modelmapper/modelmapper
implementation group: 'org.modelmapper', name: 'modelmapper', version: '3.1.1'
@Configuration
public class CustomModelMapper {
private final ModelMapper modelMapper = new ModelMapper();
@Bean
public ModelMapper strictModelMapper() {
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
return modelMapper;
}
@Bean
public ModelMapper standardModelMapper() {
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STANDARD);
return modelMapper;
}
@Bean
public ModelMapper looseModelMapper() {
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.LOOSE);
return modelMapper;
}
}
// source는 camelCase, destination은 under_score 형태일 때
modelMapper.getConfiguration()
.setSourceNameTokenizer(NameTokenizers.CAMEL_CASE)
.setDestinationNameTokenizer(NameTokenizers.UNDERSCORE);
// User -> UserDTO 매핑설정
modelMapper.createTypeMap(User.class, UserDTO.class)
.addMapping(User::getName, UserDTO::setUserName) //addMapping
.addMapping(User::getEmail, UserDTO::setID)
.addMappings(mapping -> { // 한번에 여러개 매핑.
mapping.map(source -> source.getGroupName(), UserDTO::setGroupName);
mapping.map(User::getUserNo, UserDTO::setNo);
})
typeMap.addMappings(mapping -> {
mapping.skip(UserDTO::setField);
});
modelMapper.getConfiguration().setSkipNullEnabled(true);
typeMap.addMappings(mapper -> mapper.when(
ctx ->
!ObjectUtils.isEmpty(ctx.getSource())
).map(UserDTO::getPassword, PersonDTO::setPassword));