JAVA
model mapping 라이브러리 Mapstruct
91cm
2021. 7. 8. 23:02
Mapstruct란?
모델간 맵핑을 쉽게 해주는 라이브러이다 ex) entity <-> dto
-컴파일 시점에 맵핑클래스를 생성함(그래서 매우 좋음 바로바로 확인가능)
-ModelMapper 보다 맵핑 성능이 훨씬 좋음
1. 라이브러리 추가
mapstruct만 추가해주면된다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-hystrix'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:2.1.1.RELEASE'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
annotationProcessor "org.mapstruct:mapstruct-processor:1.3.1.Final"
runtimeOnly 'com.h2database:h2'
// mapstruct!! 추가
implementation 'org.mapstruct:mapstruct:1.3.1.Final'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
2. 예제 DTO , Entity 생성
2-1 DTO
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@ToString
@Getter @Setter
@NoArgsConstructor // 기본생성자 필수!
@AllArgsConstructor // 테스트코드 작성을 위해 추가
public class UserDto {
private String nameModel;
private int ageModel;
private String addrModel;
}
2-2 Entity
실제 Entity로 만들진 않았지만, Entity 역할을 하는 model로 테스트 진행 예정
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@ToString
@Getter @Setter
@NoArgsConstructor // 기본 생성자 필수!
@AllArgsConstructor // 테스트코드 작성을 위해 추가
public class User {
private String name;
private int age;
private String addr;
}
3. mapper 인터페이스 생성*중요
source : 맵핑시킬 멤버 필드명
target : 맵핑되어질 멤버 필드명
ignor : 해당 멤버필드는 맵핑하지 않음
참고 : 멤버 필드명이 양쪽이 모두 같다면 속성명시는 생략가능.
import com.example.test.test.dto.UserDto;
import com.example.test.test.dto.User;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper // mapstruct를 사용하기 위해 선언
public interface UserMapper {
//UserMapper를 상속받아 구현체가 작성됨 , build 폴더가보면 확인가능. UserMapperImpl이 생성됨
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
// Entity를 DTO로 맵핑
@Mapping(source = "name", target ="nameModel")
@Mapping(source = "age", target ="ageModel")
@Mapping(source = "addr", target ="addrModel")
UserDto userEntityToUserDto(User user);
// DTO를 Entity로 맵핑
@Mapping(source = "nameModel", target = "name")
@Mapping(source = "ageModel", target = "age")
@Mapping(source = "addrModel", target = "addr")
User userDtoToUserEntity(UserDto userDto);
// 특정 컬럼을 제외하고 맵핑 (ignore속성)
@Mapping(target ="addr", ignore = true)
@Mapping(target = "name" , source = "nameModel")
@Mapping(target = "age" , source = "ageModel")
User userDtoToEntityAndIgnore(UserDto userDto);
}
4. 테스트 코드 작성
import com.example.test.test.dto.User;
import com.example.test.test.dto.UserDto;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class UserMapperTest {
@Test
public void DTO를_Entity로_맵핑() {
UserDto userDto = new UserDto("민", 20, "서울");
User user = UserMapper.INSTANCE.userDtoToUserEntity(userDto);
System.out.println(">>>>> userDto = " + userDto);
System.out.println(">>>>> user = " + user);
Assertions.assertEquals("민", user.getName());
Assertions.assertEquals(20, user.getAge());
Assertions.assertEquals("서울", user.getAddr());
}
@Test
public void Entity를_DTO로_맵핑() {
User user = new User("민", 20, "서울");
UserDto userDto = UserMapper.INSTANCE.userEntityToUserDto(user);
System.out.println(">>>>> user = " + user);
System.out.println(">>>>> userDto = " + userDto);
Assertions.assertEquals("민", userDto.getNameModel());
Assertions.assertEquals(20, userDto.getAgeModel());
Assertions.assertEquals("서울", userDto.getAddrModel());
}
@Test
public void 주소필드는_무시하고_맵핑() {
UserDto userDto = new UserDto("민", 20, "서울");
User user = UserMapper.INSTANCE.userDtoToEntityAndIgnore(userDto);
System.out.println(">>>>> userDto = " + userDto);
System.out.println(">>>>> user = " + user);
Assertions.assertEquals("민", user.getName());
Assertions.assertEquals(20, user.getAge());
Assertions.assertEquals(null, user.getAddr());
}
}
5.결과 성공
