회원 정보를 수정하기 위해서 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);
}