Free Lines Arrow
본문 바로가기
Spring/spring

[Spring] ModelMapper

by skahn1215 2022. 3. 12.
728x90
반응형

Modelmapper

  • 모델 맵퍼에 대해서 알아보자.
  • 기본적인 사용 방법과 사용시 문제가 될만한 부분을 알아본다.
  • 프로젝트를 진행하다 보면 DTO 를 만들게 된다.
  • 모델을 DTO로 쉽게 변환해주기때문에 사용한다.
  • 사용할때 유의점은 ACCESSLEVEL 또는 setter 둘중 하나는 반드시 필요하다.
  • 값이 null로 떨어지는 문제를 해결해본다.

 

DTO (DataTransferObject)를 만드는 이유?

  • 간단하게 설명하자면 요청비용이 비싸고 자바의 특성상 여러개의 값을 리턴할수없다.
  • 모델에는 다양한 어노테이션 또는 로직이 들어 갈수 있기 모델 자체를 전달하는건 적합하지 않다고 생각한다.
  • 그렇기 때문에 DTO 를 만들어서 사용한다.

 

ModelMapper 의 특징

Intelligent

  • 모델 맵퍼는 어떻게 데이터를 맵핑할지 지능적으로 결정한다.
  • 수동맵핑이 필요없다

Refactoring Safe

  • 실제 코드를 사용하여 속성과 값을 맵핑시킨다.
  • 문자가 아니 실제 코드를 사용함으로써 타입과 리팩토링에 대한 안정성이 있다.

Convention Based

  • ModelMapper 컨벤션을 사용하여 어떻게 맵핑할지 결정한다.
  • 이러한 관례를 따르면서 실수와 에러를 방지 할 수 있다.

Extensible

  • 확장성이 있다.
  • ModelMapper는 모든 유형의 데이터 모델과의 통합을 지원한다.
  • JavaBeans 및 JSON 트리에서 데이터베이스 레코드등등

 

Matching Strategies

Standard

  • Default 전략이다.

규칙

  • 1. 토큰 순서와 상관없이 매칭시킨다.
  • 2. 모든 대상 속성 이름 토큰이 일치해야 된다.
  • 3. 모든 원본 속성 이름에는 하나 이상의 토큰이 일치해야 합니다.
phoneNumber => numberPhone 맵핑 가능(규칙1 가능)
phoneNumber => number      맵핑 가능(규칙2 가능)
phoneNumber => phone       맵핑 가능(규칙2 가능)

phoneNumber => cellPhone   불가능(규칙2 위반)
phoneNumber => numPhone    불가능(규칙3 위반)

 

Loose

  • Standard 보다 느슨한 규칙을 가진다
  • 이건 실무에서 사용하면 안된다 애매하게 맵핑 되거나 잘못 맵핑 될수가 있다.

규칙

  • 1. 토큰은 임의의 순서로 일치시킨다.
  • 2. 마지막 대상 속성 이름에 모든 토큰이 일치해야 합니다.
  • 3. 마지막 원본 속성 이름에 하나 이상의 토큰이 일치해야 합니다.
phoneNumber => numberPhone 맵핑 가능
phoneNumber => number      맵핑 가능
phoneNumber => phone       맵핑 가능
phoneNumber => cellPhone   맵핑 가능
phoneNumber => numPhone    맵핑 가능

 

Strict

  • 엄격하게 검사하여 맵핑을 한다.

규칙

  • 토큰은 엄격한 순서로 일치합니다.
  • 모든 대상 속성 이름 토큰이 일치해야 합니다.
  • 모든 원본 속성 이름에는 모든 토큰이 일치해야 합니다.
phoneNumber => PhoneNumber 가능

phoneNumber => numberPhone 불가능
phoneNumber => number      불가능
phoneNumber => phone       불가능
phoneNumber => cellPhone   불가능
phoneNumber => numPhone    불가능

 

 

AccessLevel

  • 왜 맵핑을 했는데 Null 값이 뜰까?
  • ModelMapper 는 기본적으로 AccessLevel이 public 으로 되어 있다(public 변수만 맵핑을 할수 있다)
  • setter 를 만들어 주거나 AccessLevel 을 private 으로 해주자
  • ModelMapper 의 InheritingConfiguration 에서 확인 가능하다.
/**
* Creates an initial InheritingConfiguration.
*/
public InheritingConfiguration() {
    ...
    fieldAccessLevel = AccessLevel.PUBLIC;
    methodAccessLevel = AccessLevel.PUBLIC;
    ...
}

 

 

맵핑 실패 예제

ModelMapper modelMapper = new ModelMapper();

Customer customer = new Customer("이름", 33, "주소", "번호");
CustomerDto customerDto = modelMapper.map(customer, CustomerDto.class);

System.out.println(customerDto.toString());

결과

// 값이 맵핑이 안됐다.
CustomerDto(name=null, age=0, address=null, phoneNumber=null)

 

AccessLevel 을 private 으로 변경

 ModelMapper modelMapper = new ModelMapper();

modelMapper.getConfiguration()
        .setFieldMatchingEnabled(true)
        .setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);

Customer customer = new Customer("이름", 33, "주소", "번호");
CustomerDto customerDto = modelMapper.map(customer, CustomerDto.class);

System.out.println(customerDto.toString());

결과

CustomerDto(name=이름, age=33, address=주소, phoneNumber=번호)

 


기본적인 사용방법

http://modelmapper.org/user-manual/property-mapping/#conditional-mapping

 

ModelMapper - Property Mapping

Property Mapping For most object models, ModelMapper does a good job of intelligently mapping source and destination properties. But for certain models where property and class names are very dissimilar, a PropertyMap can be created to define explicit mapp

modelmapper.org

 

 

 

 

 

 

 

참고:

http://modelmapper.org/getting-started/

728x90
반응형

댓글