1. modelMapper 란?
"서로 다른 클래스의 값을 한 번에 복사하게 도와주는 라이브러리"
어떤 Object(Source Object)에 있는 필드 값들을 자동으로 원하는 Object(Destination Object)에
Mapping 시켜주는 라이브러리이다.
그렇다면 왜 사용할까?
DTO와 같은 클래스로 데이터를 받은 후 원하는 클래스(엔티티)에 넣어줄 때, 하나씩 넣어준다면?
이때 문제가 발생한다.
- 매우 귀찮다.
- 실수가 발생할 수 있다.
이런 단점들을 해결하기 위한 라이브러리이다.
다시 말해 repository에서 사용하는 entity class형태와 필드 대부분 동일하지만 다른 형태로 구성되어 있어
entity와 dto의 변환에 사용하는 것이다.
2. modelMapper 세팅
-1) 의존성 추가
dependencies{
...
implementation 'org.modelmapper:modelmapper:3.1.0'
}
-2) config 추가
@Configuration
public class ModelMapperConfig {
@Bean
public ModelMapper modelMapper(){
return new ModelMapper();
}
}
3. modelMapper 사용법
-1) 빈 생성
@RequiredArgsConstructor
public class Controller {
private final ModelMapper mapper;
}
-2) 사용
<단일 객체 변환>
UserMapDto userMapDto = mapper.map(user, UserMapDto.class);
<리스트 변환>
List<CommentDto> commentDto = comments.stream()
.map(comment -> mapper.map(comment,CommentDto.class))
.collect(Collectors.toList());
<TypeMap 변환>
/**단일*/
modelMapper.createTypeMap(User.class, UserMapDto.class)
.addMapping(User::getName, UserDTO::setUserName)
/**다수*/
modelMapper.createTypeMap(User.class, UserMapDto.class)
.addMappings(mapping -> {
mapping.map(source -> source.getName(), UserMapDto::setName);
mapping.map(User::getUserAddress, UserMapDto::setUserAddress);
})
4. 기타 사항
-1) 전략
특정 매칭 전략을 입력해 주지 않고도 다른 매칭 전략을 사용할 수 있게끔 추가적인 매칭 전략을 제공한다.
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STANDARD) // STANDARD 전략
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.LOOSE) // LOOSE 전략
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT) // STRICT 전략
- MatchingStrategies.STANDARD(default)
- 모든 destination 객체의 property 토큰들은 매칭 되어야 한다.
- 모든 source 객체의 property들은 하나 이상의 토큰이 매칭되어야 한다.
- 토큰은 어떤 순서로든 일치될 수 있다.
- MatchingStrategies.STRICT
- 가장 엄격한 전략
- source와 destination의 타입과 필드명이 같을 때만 변환
- 의도하지 않은 매핑이 일어나는 것을 방지할 때 사용
- MatchingStrategies.LOOSE
- 가장 느슨한 전략
- 토큰을 어떤 순서로도 일치 시킬 수 있다.
- 마지막 destination 필드명은 모든 토큰이 일치해야 한다.
- 마지막 source 필드명에는 일치하는 토큰이 하나 이상 있어야 한다.
-2) Tokenizer 사용
modelMapper.getConfiguration()
.setSourceNameTokenizer(NameTokenizers.CAMEL_CASE)
.setDestinationNameTokenizer(NameTokenizers.UNDERSCORE);
-3) convert 사용
매핑 시 데이터 가공이 필요할 때 사용한다.
/** 매핑시 대문자로 가공 */
typeMap.addMappings(mapping -> mapping.using(ctx -> ((String)
ctx.getSource()).toUpperCase())
.map(User::getName, UserMapDto::setName));
-4) skip 관련
/**특정 필드 스킵*/
typeMap.addMappings(mapping -> {
mapping.skip(Destination::setFieldName);
});
/**null 필드 스킵*/
modelMapper.getConfiguration().setSkipNullEnabled(true);
**특정 null 필드 스킵*/
typeMap.addMappings(mapper -> mapper.when(ctx -> !ObjectUtils.isEmpty(ctx.getSource()))
.map(UserDTO::getPassword, PersonDTO::setPassword));
잘 사용한다면 이점이 많은 라이브러리다.
끝!
출처 및 참고 :
https://devwithpug.github.io/java/java-modelmapper/#type-map
https://codemanager.tistory.com/3
https://loosie.tistory.com/147
https://velog.io/@sdb016/ModelMapper
'👩💻 개발 > ⚙️ BACKEND' 카테고리의 다른 글
[Spring/Jpa] @Default 설정 (0) | 2022.08.12 |
---|---|
[Spring/Java] @Builder / 빌더패턴 (0) | 2022.08.12 |
[SpringBoot] Jpa Repository와 Querydsl 사용방법 (0) | 2022.08.06 |
[SpringBoot] Querydsl 설정 (1) | 2022.08.06 |
[SpringBoot] Thymleaf css, js 파일 추가 및 사용법 (0) | 2022.07.27 |