
Spring Data Jpa에서 제공하는 Page와 Pageable을 이용하면 편리하게 구현할 수 있다.
- Pageable : JPA가 DB에 접근해 데이터를 가져올 때 자동으로 limit 조건을 붙여 데이터를 가져온다.
- PageRequest : 페이지네이션 정보를 담기위한 구현제이다.
- Page : Pageable을 파라미터로 가져온 결과는
Page<Object>형태로 반환되며, Page를 사용하면Page<List<Object>>의 형태를 반환한다.
public interface ReviewRepository extends JpaRepository<Review, Long> {
@Query("select ri from Review ri " +
"where ri.item.id = :itemId " +
"order by ri.registerTime desc")
Page<Review> getReviewList(@Param("itemId") Long itemId, PageRequest pageRequest);
}
Page<Object> 로 반환을 받으면 getContent()를 통해 object를 꺼내올 수 있다.@GetMapping("/reviews/{itemId}")
public String reviews(
@PageableDefault(page=1) Pageable pageable,
@PathVariable("itemId") Long itemId,
Model model
){
Page<ReviewResponseDto> reviewResponseDtos =
reviewService.findAllByItemId(itemId,pageable)
.map(ReviewResponseDto::new);
int blockLimit = 5;
int startPage = (((int) Math.ceil(((double) pageable.getPageNumber() / blockLimit))) - 1) * blockLimit + 1;
int endPage = Math.min((startPage + blockLimit - 1), reviewResponseDtos.getTotalPages());
model.addAttribute("reviews",reviewResponseDtos);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("itemId",itemId);
return "review/reviewList";
}
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
public Page<Review> findAllByItemId(Long itemId,Pageable pageable){
int page = pageable.getPageNumber()-1;
int pageSize = 5;
Page<Review> reviewList = reviewRepository.getReviewList(itemId,PageRequest.of(page, pageSize));
return reviewList;
}
PageRequest page = PageRequest.of(페이지 순서, 페이지 크기)sort혹은 direction을 사용하여 정렬을 설정할 수 있다.// EX) 내림차순 정렬
PageRequest.of(페이지 순서, 페이지 크기, Sort.by(Direction.DESC, "price"));
PageRequest.of(페이지 순서, 페이지 크기, Sort.by(Order.desc("price")));
PageRequest.of(페이지 순서, 페이지 크기, Direction.DESC, "price");
<div>
<ul class="pagination justify-content-center">
<li class="page-item">
<a class="page-link" th:href="@{/reviews/{itemId}(itemId=${itemId},page=1)}">첫 페이지 </a>
</li>
<li class="page-item">
<a class="page-link" th:href="${reviews.first} ? '#' : @{/reviews/{itemId}(itemId=${itemId},page=${reviews.number})}"> 이전 </a>
</li>
<span class="page-item" th:each="page: ${#numbers.sequence(startPage, endPage)}">
<li class="page-item active" th:if="${page == reviews.number + 1}">
<a class="page-link" th:text="${page}"></a>
</li>
<li class="page-item" th:unless="${page == reviews.number + 1}">
<a class="page-link" th:href="@{/reviews/{itemId}(itemId=${itemId}, page=${page})}" th:text="${page}"></a>
</li>
</span>
<li class="page-item">
<a class="page-link" th:href="${reviews.last} ? '#' : @{/reviews/{itemId}(itemId=${itemId},page=${reviews.number + 2})}"> 다음 </a>
</li>
<li class="page-item">
<a class="page-link" th:href="@{/reviews/{itemId}(itemId=${itemId},page=${reviews.totalPages})}"> 마지막 페이지</a>
</li>
</ul>
</div>