Backend/SpringBoot

@Mapper, @Mapping

Dean83 2024. 11. 20. 12:02

DTO와 Entity 간 상호 변환을 위해 사용되는 어노테이션이다.  MapStruct 라이브러리를 사용한다. 

@Mapper 는 인터페이스에 붙이는 어노테이션이고, @Mapping 은 실제 상호 변환을 하는 함수명에 붙이는 어노테이션 이다. 

그래들에 다음을 추가한다.

dependencies {
    ...
    implementation 'org.mapstruct:mapstruct:1.6.3'
 
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.6.3'
}

 

  • @Mapping (source = "변수명", target = "변수명")
    • 소스 변수명을 타겟 변수명으로 치환하는 설정을 한다. 
    • 변수명이 여러개 일 경우 @Mapping 어노테이션을 해당 개수에 맞춰 여러개 붙여준다. 
    • 만일 변수명이 엔티티, DTO 모두 동일하다면 사용하지 않아도 된다.
  • @Mapper
    • 인터페이스에 붙인다. 
    • Mappers.getMappers(클래스명.class) 를 통해 Instance 를 생성해준다
      • 이를 하지 않을 경우 @Mapper(componentModel = "spring") 를 명시해야 bean 으로 등록 한다.
      • Mappers 를 사용하는것이 현재 기준 공식 문서에서 추천하는 방식이다.
  • Getter, Setter 설정 필요
    • Getter, Setter 가 없다면, Mapper 가 변환을 할 수가 없으므로, 양방향 변환이 필요한 경우 DTO 와 엔티티에 모두 있어야 한다
    • 만일 단방향 (예 : 엔티티 -> DTO) 라면, 엔티티에는 Getter만, DTO 는 둘 다 있어야 한다.

 

다음은 예제이다. 

/////Entity가 다음과 같다고 가정/////

...

@Entity
@Getter
@Setter
public class EntityData
{
	...
	private String val1;
    private String val2;
    private String val3;
    ....
    
}


///DTO가 다음과 같다고 가정////

...

@Getter
@Setter
public class TestDTO
{
	...
    private String name;
    private String addr;
    private String phone;
    ...
}


////Mapper 예/////

@Mapper
public interface MapperTest
{
	MapperTest INSTANCE = Mappers.getMapper(MapperTest.class); 

	@Mapping (source = "val1", target = "name")
    @Mapping (source = "val2", target = "addr")
    @Mapping (source = "val3", target = "phone")    
    public TestDTO fromEntity(EntityData entity);
    
    @Mapping (source = "name", target = "val1")
    @Mapping (source = "addr", target = "val2")
    @Mapping (source = "phone", target = "val3")    
    public EntityData fromDTO(TestDTO dto);
}




////서비스에서 활용 예/////

...
@Service
public class TestService
{
    private TestRepository repo;
    
    //DI 인젝션
    TestService(TestRepository r)
    {
        repo = r;
    }
    
    public TestDTO GetDTO(long id)
    {
    	EntityData data = repo.findById(id);
        return MapperTest.INSTANCE.fromEntity(data);
    }
    
    public void SaveData(TestDTO dto)
    {
    	repo.save(MapperTest.INSTANCE.fromDTO(dto));
    }
}

'Backend > SpringBoot' 카테고리의 다른 글

자바스크립트에서 타임리프 사용하기 (+onclick 인자 전달)  (0) 2024.12.18
전반적인 프로젝트 구조  (0) 2024.11.26
실행시 DB에 데이터 넣기  (1) 2024.11.19
AOP (함수 실행 intercept)  (0) 2024.10.30
QueryDSL  (0) 2024.10.30