만약 게시판을 만들었을 때 게시글이 10000개가 넘었다면 이걸 어떻게 보기 쉽게할까?
당연히 아래에 1 2 3 4 5 6 과 같이 페이지 번호를 만들고 숫자를 누르면 게시글을 순서대로 N개씩 끊어서 볼 수 있도록 구현하고싶을것이다.
이것을 페이지네이션(페이징) 이라고 한다!
JPA에서는 Pageable
과 Page
인터페이스를 활용하여 페이징 처리를 간편하게 할 수 있다.
Pageable 인터페이스는 페이지 관련 정보를 포함하고 있다. 주로 데이터베이스로부터 특정 범위의 결과를 가져오는 데 사용된다. 이를 통해 페이징된 데이터를 요청하고 결과를 받아올 수 있다.
Pageable pageable = PageRequest.of(pageNumber, pageSize);
여기서 pageNumber은 요청하는 페이지 번호를, pageSize는 한 페이지에 표시할 항목의 수를 나타낸다.
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";
}
<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랑 뷰단에서 처리하니까 정말 쉽죠?