코딩마을방범대
ModelMapper란 본문
728x90
ModelMapper란
- 서로 다른 클래스의 값을 한번에 복사하게 도와주는 라이브러리
- DTO와 Entity를 변환할 때 Getter, Setter을 이용할 경우 번거롭기 때문에 사용
modelmapper는 런타임시점에 리플렉션이 발생하므로 성능 저하가 매우 심함
컴파일 시점에 코드가 생성되는 mapstruct 사용하는 것을 권장
사용법
1. build.gradle
// https://mvnrepository.com/artifact/org.modelmapper/modelmapper
implementation group: 'org.modelmapper', name: 'modelmapper', version: '3.1.1'
2. Configuration
@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;
}
}
- STANDARD(default)
- source와 destination 속성과 지능적으로 일치 시킴
- 모든 destination 속성 이름 토큰이 일치해야 함
- 모든 source 속성 이름은 일치하는 토큰이 하나 이상 있어야 함
- 토큰들은 어떤 순서로든 일치될 수 있음
- STRICT
- 가장 엄격한 전략
- source와 destination의 타입과 필드명이 같을 때만 변환
- 의도하지 않은 매핑이 일어나는 것을 방지할 때 사용
- 토큰들은 순서가 일치해야함
- LOOSE
- 가장 느슨한 전략
- 속성 계층 구조가 매우 다른 source, destination 객체에 사용하는 데에 이상적
- 토큰들은 어떤 순서로든 일치될 수 있음
- 마지막 destination 필드명은 모든 토큰이 일치해야함
- 마지막 source 필드명에는 일치하는 토큰이 하나 이상 있어야 함
- 의도하지 않은 매핑이 될 확률이 높아 잘 사용하지 않음
Tokenizer
- source 필드명과 destination의 필드명이 다를 때 사용
// source는 camelCase, destination은 under_score 형태일 때
modelMapper.getConfiguration()
.setSourceNameTokenizer(NameTokenizers.CAMEL_CASE)
.setDestinationNameTokenizer(NameTokenizers.UNDERSCORE);
Mapping 설정
- 일치하지 않는 필드명이나 구조가 있더라도 필드들을 매핑시킬 수 있음
// 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);
})
Converter를 이용한 데이터 가공
- skip
- destination 필드 중 매핑하고 싶지 않은 필드가 있을 때
typeMap.addMappings(mapping -> { mapping.skip(UserDTO::setField); });
- Null 필드 skip
- null로 넘어오는 필드를 제외하고 업데이트 하고 싶을 때 (DTO -> Entity)
- 모든 필드들에 대해 작동하기 때문에 특정 필드만 대상으로 skip하고 싶다면 아래의 Conditional Mapping을 사용
modelMapper.getConfiguration().setSkipNullEnabled(true);
- Conditional Mapping
- 특정 필드가 null일 경우 매핑하고 싶지 않을 때 (DTO -> Entity)
typeMap.addMappings(mapper -> mapper.when( ctx -> !ObjectUtils.isEmpty(ctx.getSource()) ).map(UserDTO::getPassword, PersonDTO::setPassword));
728x90
'💡 백엔드 > Java' 카테고리의 다른 글
SHA-256 해싱 알고리즘 (0) | 2023.05.26 |
---|---|
JAVA에서의 암호화 방법 (AES) (0) | 2023.05.26 |
Autowired를 지양하는 이유 & 정규표현식 (0) | 2023.05.25 |
스케쥴러(Scheduler)에 대하여 (1) | 2023.05.25 |
SpringBoot에서 JSON 활용하기 (0) | 2023.05.25 |