230325 TIL #42 JPA 중복체크 .exists() / TOP

김춘복·2023년 3월 24일
0

TIL : Today I Learned

목록 보기
42/543
post-custom-banner

230325 Today I Learned

클론코딩 2일차. 저번주에 미니프로젝트를 한 덕분에 ci/cd까지 무리없이 하루만에 진행했다. 그래서 오늘은 JPA에 대해 좀 더 공부를 해보며 리팩토링을 진행했다.


중복체크

  • 문제 : 회원가입시 유저명이나 닉네임, 이메일 중복체크 유효성검사를 할 때 기존에는 아래와 같은 방식을 사용했다.
//회원중복 확인
        Optional<User> found = userRepository.findByUsername(email);
        if (found.isPresent()) {
            throw new IllegalArgumentException("중복된 email 입니다.");
        }

이렇게 코드를 쓰니 굳이 쓰지도 않을 user변수를 Optional로 받아서 .isPresent()로 확인해야되냐는 지적을 받았다.

  • 시도 및 해결 : JPA 를 좀 더 공부해 보니 .existBy(파라미터)로 존재여부를 확인하여 boolean 값으로 반환하는 메서드가 있어 활용해 봤다.
    아래는 해당 방법을 활용해 email 체크를 하는 메서드를 만들었다.
public MessageResponseDto CheckEmail(CheckEmailRequestDto dto) {
        boolean isEmailExist = userRepository.existsByEmail(dto.getEmail());
        return isEmailExist
                ? new MessageResponseDto(HttpStatus.BAD_REQUEST, "중복된 이메일입니다.")
                : new MessageResponseDto(HttpStatus.OK, "사용가능한 이메일입니다.");
    }

True면 이메일이 있으니 중복 메세지를 반환하고, False면 이메일이 없으니 사용가능하다고 메세지를 반환하도록 설계했다. 이렇게 하니 좀 더 간결하고 가독성이 좋아졌다.

  • 알게된 점 : JPA 에서 .existBy(파라미터) 사용.

TOP

  • 문제 : 상품 상세 조회시 최신 상품 6개를 List로 같이 반환 해주는 코드를 짰는데
    이전 프로젝트에서는 게시글 전체를 반환하는 메서드를 써서 고치고 싶었다.
    List<Post> posts = postRepository.findAllByOrderByCreatedAtDesc();

  • 시도 및 해결 :

List<ProductListResponseDto> productListResponseDtos = productRepository
                .findTop6ByIdNotAndIsDoneFalseOrderByCreatedAtDesc(id).stream()
                .map(ProductListResponseDto::new)
                .collect(Collectors.toList());

findTop6ByIdNotAndIsDoneFalseOrderByCreatedAtDesc(id)
: 주어진 id(현재 상품)은 제외하고 작성시간순으로 가장 최신 상품 상위 6개만 리스트에 담아서 가져오는 JPA 메서드이다. 이처럼 Top을 사용할 시 상위 N개의 객체만 가져올 수 있다.

하지만 이렇게 top을 쓸 경우 전체를 일단 가져와서 정렬을하고 상위 6개를 추려내서 반환을 하는 방식이라 성능에서 아쉬움이 있었다.

그래서 아래처럼 page를 쓸 경우 5개만 딱 검색을 해서 반환하기 때문에 db에 부하가 적을 것으로 생각이 되었지만 에러가 발생해서 당장은 적용하지 못했다.

    List<ProductListResponseDto> productListResponseDtos = productRepository
            .findByIdNotInAndIsDoneFalseOrderByCreatedAtDesc(pdid, PageRequest.of(0, 5)).stream()
            .map(ProductListResponseDto::new)
            .collect(Collectors.toList());

이 부분은 남은 프로젝트동안 고민을 하고 적용해봐야 할 것 같다.

profile
Backend Dev / Data Engineer
post-custom-banner

0개의 댓글