본문 바로가기
TIL

Plmography 프로젝트 작업 로그 #30 - Java 의 Pageable 클래스 (23.01.11 TIL)

by winteringg 2023. 1. 11.

이번주는 프론트 구현에 힘을 싣기로 한 만큼 어제부터 프론트에만 집중하고 있는데 하나 건너 하나 오류 해결중이다..ㅋㅋㅋ 오늘의 디버깅 포인트는 페이징 기능을 구현하기 위해 레포지토리에 정의한 Pageable 클래스 였다. 코드는 아래와 같다.

// repository layer
public interface ReviewRepository extends JpaRepository<Review, Long> {
    Page<Review> findAllByUserId(UserId userId, Pageable pageable);
}


// controller layer
@GetMapping
    public ReviewsDto list(
    	    @RequestAttribute Long userId,
            @RequestParam(required = false, defaultValue = "1") Integer page,
            @RequestParam(required = false, defaultValue = "5") Integer size
    ) {

        return getReviewsService.reviews(userId, page, size);
    }
    
    
// service layer
public ReviewsDto reviews(Long userId, Integer page, Integer size) {
    Sort sort = Sort.by("createdAt").descending();

    Pageable pageable = PageRequest.of(page - 1, size, sort);

    Page<Review> reviews = reviewRepository.findAllByUserId(new UserId(userId), pageable);

    List<ReviewDto> reviewDtos = reviews.stream()
            .map(review -> {
            
                ...생략...

                return new ReviewDto(
                
                        ....생략....
                        
            }).toList();

    PagesDto pagesDto = new PagesDto(reviews.getTotalPages());

    return new ReviewsDto(reviewDtos, pagesDto);
}


먼저 나는 서버에 등록된 모든 리뷰를 가져오는 기능을 페이징 처리와 함께  구현하고 싶었다. 그래서 레포지토리에 findAllByUserId 를 Pageable 로 만들고, 서비스 레이어에서 해당 유저 아이디가 포함된 리뷰들을 모두 가져온다. 그렇게 Page 클래스로 가져온 리뷰들을 map 으로 stream 돌린 후 List 에 담아서 DTO 로 반환한다.

일단 여기서 맞지 않는 논리적 오류는, 서버에 등록된 모든 리뷰를 가져오는 것이면 findAll 을 써야하는데, 특정 유저 id 의 리뷰를 가져오는 findAllByUserId 를 만들어 쓴 것이었다. 여기서 논리적 결함을 알아채지 못했고, 열심히 콘솔로 디버깅을 하고 있었던 것..

게다가 나는 컨트롤러에서 size 의 디폴트 값을 5로 정해놨는데 마침 서버에 이미 등록되어 있는 리뷰도 5개였다. Page<Review> reviews 의 getSize() 메서드가 있길래 레포지토리에서 모두 가져온 리뷰가 담긴 리스트 형태를 출력해준다고 생각해서 디버깅할 때 사용했는데 계속 5 가 출력되어서 리뷰 5개의 값이 잘 들어온다고 생각했다. 레포지토리에서 모두 찾아와서 저장했으니까 Page 클래스의 reviews 를 List 형태와 비슷하다고 혼자 오해해버린 것이다. 그리고 그걸 다시 List 로 만들어서 map 을 돌리면 리뷰가 딱 한 개만 출력되니까 map 이 써져있는 로직에서 오류가 있을 것이라고 추측했다.

이걸 해결하는데에 거의 오후를 다 써버려서 1기 동료분의 도움을 청해 다시 찬찬히 디버깅을 했고, findAllByUserId 라는 메서드가 잘못 된 것을 깨달아 findAll() 로 바꿔주었다. 그리고 필요 없어진 @RequestAttribute 로 받아오는 userId 를 없애주었다. 그랬더니 바로 map 이 제대로 작동하면서 (원래도 제대로 작동했지만) 리뷰 5개가 올바르게 출력되었다. 

그렇다면 여기서 의문은, Page 의 getSize() 메서드는 무슨 역할을 하는 것일까 인데, 찾아보니 이름 그대로 한 페이지의 size 를 돌려주는 메서드였다.

메소드 설명
int getNumber() 현재 페이지의 정보
int getSize() 한 페이지의 크기
int getTotalPages 전체 페이지의 수
int getNumberOfElements() 결과 데이터 수
boolean hasPreviousPage() 이전 페이지의 존재 여부
boolean hasNextPage() 다음 페이지의 존재 여부
boolean isLastPage() 마지막 페이지 여부
Pageable nextPageable() 다음 페이지 객체
Pageable previousPageable() 이전 페이지 객체
List<T> getContent() 조회된 데이터
boolean hasContent() 결과 존재 여부
Sort getSort() 검색 시 사용된 Sort 정보

내가 디폴트로 정한 size 의 값과 실제 서버에 등록된 리뷰의 개수가 우연히 동일해서 더 빨리 알아채지 못했지만,,,,,,,,,,그래도 해결했다! 이제 다시 진도를 나가보자..

댓글