현의 개발 블로그

JPA 페이징 구현하기(1) 본문

대외활동/한이음

JPA 페이징 구현하기(1)

hyun2371 2023. 7. 20. 17:41

페이징은 한 번에 가져오는 데이터의 양을 제한하는 것이다.

Pageable 인터페이스를 사용하여 쉽게 구현할 수 있다.

 

코드 구현

PageResponse<T> 클래스 추가

@Getter
@AllArgsConstructor
public class PageResponse<T>{
    private int currentPage;//현재 페이지 수
    private int totalPages; //전체 페이지 수
    private long totalItems; //전체 데이터 수
    private List<T> items; //페이지에 포함될 실제 데이터

    public static <T> PageResponse<T> fromPage(Page<T> page){
        return new PageResponse<>(
            page.getNumber(), 
            page.getTotalPages(),
            page.getTotalElements(), 
            page.getContent()
        )
    }
}

Spring Data의 Page 객체를 사용자 정의 객체로 반환하기 위해 PageResponse를 정의한다.

<T> 는 제네릭 타입으로, 사용할 때 어떤 타입의 객체로 페이징할지 정할 수 있다.

 

Repository 작성

public interface BookmarkRepository extends JpaRepository<Bookmark, Long> {
    Page<Bookmark> findAllByUser(User user, Pageable pageable);
}

Pageable이 파라미터로 들어가고 반환타입도 Page<객체> 형태가 된다.

 

Controller 작성

@GetMapping("/{userId}")
public BaseResponse<PageResponse<BookmarkRes>> getUserBookmarks(
        @PathVariable Long userId, 
        @RequestParam(required = false, defaultValue = "0") int pageNo,
        @RequestParam(required = false, defaultValue = "10") int pageSize) {
    return bookmarkService.getUserBookmarks(userId, pageNo, pageSize);
}

required=false, defaultValue = "0"

파라미터를 정의해주지 않으면 기본값으로 설정되도록 하였다.

 

pageNo는 현재 페이지 번호로 0부터 시작한다.

pageSize는 한 페이지에 표시할 아이템 수를 말한다.

 

 

Service 작성

public BaseResponse<PageResponse<BookmarkRes>> getUserBookmarks(Long userId, int page, int size) {
    User user = userRepository.findById(userId).orElse(null);
    if (user==null){
        return new BaseResponse<>(BaseResponseStatus.NOT_EXIST_USER_ID);
    }
    //Pageable 객체 생성
    Pageable pageable = PageRequest.of(pageNo, pageSize);
    
    //페이징된 데이터 조회
    Page<Bookmark> pagedBookmarks = bookmarkRepository.findAllByUser(user, pageable);
	
    //Page<Bookmark> -> Page<BookmarkRes>
    Page<BookmarkRes> bookmarkResPage = pagedBookmarks.map(BookmarkRes::of);
    
    //Page<> -> PageResponse<>
    PageResponse<BookmarkRes> pageResponse = PageResponse.fromPage(bookmarkResPage);

    return new BaseResponse<>(pageResponse);
}

 

하나씩 살펴보자

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

Pageable.of는 Spring Data의 인터페이스를 구현한 메서드이다.

페이징과 관련된 요청 정보를 생성하고 이에 맞는 Pageable 객체를 반환한다.

 

Page<BookmarkRes> bookmarkResPage = pagedBookmarks.map(BookmarkRes::of);

Page<Bookmark>를 Page<BookmarkRes>로 변환한다.

map()으로 각 페이지에 포함된 모든 항목에 형변환을 한다.

 

PageResponse<BookmarkRes> pageResponse = PageResponse.fromPage(bookmarkResPage);

Page<BookmarkRes>를 PageResponse<BookmarkRes>로 변환한다.

 

return new BaseResponse<>(pageResponse);

정의해둔 기본 응답으로 한번 더 감싼다.

pageResponse<BookmarkRes>로만 반환하고 싶은 경우

return PaseResponse.fromPage(bookmarkResPage); 을 해준다.

 

 

결과

 

 

 

 

Comments