반응형

MapStruct

설명

  • 하나의 객체를 다른 객체로 변환하는 작업을 해주는 매핑 라이브러리
  • 리플렉션을 사용하지 않고 컴파일 시점에 변환 코드가 생성되므로 매핑 속도가 빠르고 디버깅이 쉽다.
  • 매핑 라이브러리 중 가장 많이 사용되고 있다.

기본

dependencies {
    ...
    compileOnly 'org.projectlombok:lombok'
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    
    // lombok이 mapstruct보다 먼저 선언되어야함
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String id;
    private String password;
    private String name;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {
    private String id;
    private String name;
}
@Mapper
public interface UserMapper {
    UserDto userToUserDto(User user);
}
public class MapStructTest {
    private final UserMapper userMapper = new UserMapperImpl();

    @Test
    public void test() {
        User user = new User("u1", "1234", "john");
        UserDto userDto = userMapper.userToUserDto(user);

        assertEquals(user.getId(), userDto.getId());
        assertEquals(user.getName(), userDto.getName());
    }
}

서로 다른 속성 매핑

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String id;
    private String password;
    private String name;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {
    private String userId;
    private String username;
    private String version;
    private String message;
}
@Mapper
public interface UserMapper {
    @Mappings({
        @Mapping(target = "userId", source = "user.id"),
        @Mapping(target = "username", source = "user.name"),
        @Mapping(target = "version", constant = "v1"),
        @Mapping(target = "message", expression = "java(\"Hi, \" + user.getName())"),
    })
    UserDto userToUserDto(User user);
}
public class MapStructTest {
    private final UserMapper userMapper = new UserMapperImpl();

    @Test
    public void test() {
        User user = new User("u1", "1234", "john");
        UserDto userDto = userMapper.userToUserDto(user);

        assertEquals(user.getId(), userDto.getUserId());
        assertEquals(user.getName(), userDto.getUsername());
        assertEquals("v1", userDto.getVersion());
        assertEquals("Hi, john", userDto.getMessage());
    }
}

객체 합치기-1

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String id;
    private String password;
    private String name;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {
    private String userId;
    private String username;
    private String email;
}
@Mapper
public interface UserMapper {
    @Mappings({
        @Mapping(target = "userId", source = "user.id"),
        @Mapping(target = "username", source = "user.name")
    })
    UserDto userToUserDto(User user, String email);
}
public class MapStructTest {
    private final UserMapper userMapper = new UserMapperImpl();

    @Test
    public void test() {
        User user = new User("u1", "1234", "john");
        String email = "john@example.com";
        UserDto userDto = userMapper.userToUserDto(user, email);

        assertEquals(user.getId(), userDto.getUserId());
        assertEquals(user.getName(), userDto.getUsername());
        assertEquals(email, userDto.getEmail());
    }
}

객체 합치기-2

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String id;
    private String password;
    private String name;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Address {
    private String address;
    private String zipcode;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {
    private String userId;
    private String username;
    private Address address;
}
@Mapper
public interface UserMapper {
    @Mappings({
        @Mapping(target = "userId", source = "user.id"),
        @Mapping(target = "username", source = "user.name"),
        @Mapping(target = "address", source = "address"),
    })
    UserDto userToUserDto(User user, Address address);
}
public class MapStructTest {
    private final UserMapper userMapper = new UserMapperImpl();

    @Test
    public void test() {
        User user = new User("u1", "1234", "john");
        Address address = new Address("Seoul", "000-000");
        UserDto userDto = userMapper.userToUserDto(user, address);

        assertEquals(user.getId(), userDto.getUserId());
        assertEquals(user.getName(), userDto.getUsername());
        assertEquals(address.getAddress(), userDto.getAddress().getAddress());
    }
}

속성 제외

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private String id;
    private String password;
    private String name;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserDto {
    private String id;
    private String name;
}
@Mapper
public interface UserMapper {
    @Mappings({
        @Mapping(target = "id", ignore = true),
    })
    UserDto userToUserDto(User user);
}
public class MapStructTest {
    private final UserMapper userMapper = new UserMapperImpl();

    @Test
    public void test() {
        User user = new User("u1", "1234", "john");
        UserDto userDto = userMapper.userToUserDto(user);

        assertNull(userDto.getId());
        assertEquals(user.getName(), userDto.getName());
    }
}

참고

반응형

'Development > Spring' 카테고리의 다른 글

[Spring] Sharding  (0) 2021.07.07
[Spring] Thymeleaf  (0) 2021.06.26
[Spring] Spring Security  (0) 2021.05.29
[Spring] spring-retry  (0) 2021.05.27
[Spring] DataSource  (0) 2021.05.19

+ Recent posts