JPA Partial Update using Mapstruct

송준희·2021년 7월 26일
0

회원 정보를 수정하기 위해서 api를 만들었다.
@PatchMapping을 이용하여 변경된 값만 update를 해주고 싶었다.

    @ApiOperation(value = "회원 정보 수정")
    @PatchMapping("/v1/api/auth/update")
    @ResponseStatus(HttpStatus.OK)
    public void updateUserInfo(
            @UserInfo AuthInfo user,
            @RequestBody UserUpdateRequest userUpdateRequest
    ) {
        authService.updateUserInfo(user.getUserId(), userUpdateRequest);
    }

UserUpdateRequest는 아래와 같다.

    @Data
    public class UserUpdateRequest {
        private String userPw;
        private String userPhone;
        private String userEmail;
    }

Service단에서 entity 값을 변경하기 위해서 처음에 다음과 같이 코드를 작성했다.

    public void updateUserInfo(String userId, UserUpdateRequest userUpdateRequest) {
        User user = userRepository.findByUserIdAndUseYn(userId, 'Y').orElseThrow(UserNotFoundException::new);
        if(userPw != null)
            user.userPw = userUpdateRequest.getUserPw();
        if(userPhone != null)
            user.userPhone = userUpdateRequest.getUserPhone();
        if(userEmail != null)
            user.userEmail = userUpdateRequest.getUserEmail();
        userRepository.save(user);
    }

update할 값들이 많아질 경우 null인지 확인하는 코드를 일일이 작성해야 하기 때문에 예쁜 코드가 아니라고 생각했다.

그래서 null이 아닌 경우에만 update를 할 방법이 없을까 찾아보다가 방법을 찾아냈다.
mapStruct를 이용해서 dto를 entity와 매핑시키는 방법이다.

먼저 gradle에 아래의 코드를 추가한다.

    implementation("org.mapstruct:mapstruct:1.4.2.Final")
    annotationProcessor("org.mapstruct:mapstruct-processor:1.4.2.Final")

mapper interface를 생성하고 @Annotation을 통해 어떤 방식으로 매핑할 것인지 설정한다.
지금 같은 경우는 request에 null값이 들어오면 ignore하도록 설정했다.

@Mapper(componentModel = "spring")
public interface UserMapper {
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    void updateUserInfoFromRequest(UserUpdateRequest userUpdateRequest, @MappingTarget User user);
}

마지막으로 service단에서 mapping하는 메서드를 호출하면 아래와 같이 깔끔해진다.

    public void updateUserInfo(String userId, UserUpdateRequest userUpdateRequest) {
        User user = userRepository.findByUserIdAndUseYn(userId, 'Y').orElseThrow(UserNotFoundException::new);
        userMapper.updateUserInfoFromRequest(userUpdateRequest, user);
        userRepository.save(user);
    }

참고자료 https://www.baeldung.com/spring-data-partial-update

profile
오늘 달리면 내일 걸을 수 있다!

0개의 댓글