[Spring] JPA를 활용하여 페이징 처리 하기

이신영·2024년 5월 30일
1

Spring

목록 보기
14/16
post-thumbnail

페이징?

만약 게시판을 만들었을 때 게시글이 10000개가 넘었다면 이걸 어떻게 보기 쉽게할까?

당연히 아래에 1 2 3 4 5 6 과 같이 페이지 번호를 만들고 숫자를 누르면 게시글을 순서대로 N개씩 끊어서 볼 수 있도록 구현하고싶을것이다.

이것을 페이지네이션(페이징) 이라고 한다!


Pageable과 Page

JPA에서는 PageablePage인터페이스를 활용하여 페이징 처리를 간편하게 할 수 있다.

Pageable

Pageable 인터페이스는 페이지 관련 정보를 포함하고 있다. 주로 데이터베이스로부터 특정 범위의 결과를 가져오는 데 사용된다. 이를 통해 페이징된 데이터를 요청하고 결과를 받아올 수 있다.

Pageable pageable = PageRequest.of(pageNumber, pageSize);

여기서 pageNumber은 요청하는 페이지 번호를, pageSize는 한 페이지에 표시할 항목의 수를 나타낸다.

Page

Page 인터페이스는 페이징된 결과를 나타낸다. Pageable 인터페이스로 정의된 페이지 요청에 따라 데이터베이스로부터 가져온 결과를 포함하고 있다.

Page<Entity> page = repository.findAll(pageable);

예시

게시판을 만들고 서비스 로직에서 PageRequest로 페이징된 데이터를 받아서 컨트롤러단에 리턴해주면 컨트롤러가 그 정보들을 폼에 전송해서 페이징할 수 있도록 구현해보았다.

서비스 : pageRequest -> 컨트롤러 : addAttribute로 정보 매핑 -> 폼 : 매핑된 데이터로 처리해서 보여줌

페이징 서비스 로직

    //페이징처리된 상품리스트
    @Override
    public Page<Product> findAllProduct(int page, int size) {
        //등록날짜 DESC 페이징
        PageRequest pageRequest = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdDate"));
        return productRepository.findAll(pageRequest);
    }

컨트롤러

    @GetMapping("/list")
    public String productList(Model model,
                              @RequestParam(defaultValue = "0") int page,
                              @RequestParam(defaultValue = "10") int size) {
        Page<Product> productPage = productService.findAllProduct(page, size);
        List<Product> productList = productPage.getContent();

        model.addAttribute("productList", productList);
        model.addAttribute("currentPage", page);
        model.addAttribute("totalPages", productPage.getTotalPages());
        model.addAttribute("size", size);

        return "product/ListForm";
    }

페이징 폼(thymeleaf)

<div th:if="${totalPages > 1}">
    <div>
        <span th:if="${currentPage > 0}">
            <a th:href="@{/product/list(page=0, size=${size})}">처음</a>
            <a th:href="@{/product/list(page=${currentPage - 1}, size=${size})}">이전</a>
        </span>

        <span th:each="pageNum : ${#numbers.sequence(0, totalPages - 1)}" th:class="${pageNum == currentPage} ? 'active'">
            <a th:href="@{/product/list(page=${pageNum}, size=${size})}" th:text="${pageNum + 1}">1</a>
        </span>

        <span th:if="${currentPage < totalPages - 1}">
            <a th:href="@{/product/list(page=${currentPage + 1}, size=${size})}">다음</a>
            <a th:href="@{/product/list(page=${totalPages - 1}, size=${size})}">마지막</a>
        </span>
    </div>
</div>

첫번째 페이지

두번째 페이지

세번째(마지막) 페이지


JPA랑 뷰단에서 처리하니까 정말 쉽죠?

profile
후회하지 않는 사람이 되자 🔥

0개의 댓글