Spring Data Jpa는 페이징을 쉽게 하도록 인터페이스를 제공해준다.
PaginAndSortingRepository인데 이 인터페이스는 CrudRepository를 상속하고 있기 때문에 JpaRepository에서 구현이 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
/**
* Returns all entities sorted by the given options.
*
* @param sort
* @return all entities sorted by the given options
*/
Iterable<T> findAll(Sort sort);
/**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@code Pageable} object.
*
* @param pageable
* @return a page of entities
*/
Page<T> findAll(Pageable pageable);
}
|
cs |
Service
1
2
3
4
|
public Page<Board> getBoardList(Pageable pageable) {
return boardRepository.findAll(pageable);
}
|
cs |
Controller
1
2
3
4
5
6
7
8
9
10
|
@GetMapping("/board/list")
public String boardList(Pageable pageable, Model model) {
Page<Board> boards = boardService.getBoardList(pageable);
model.addAttribute("list", boards);
return "board/boardList";
}
|
cs |
controller에서 pageable을 인자로 받고 실행하면..
이런식으로 나오는데 이것은 "/board/list? page=0"과 같다.
임의로 page = 1로 해서 하면 아무것도 나오지 않는데 그 이유는
pageable은 sort, page, size를 지정할 수 있는데 지정 값이 20이기 때문이다.
@PageableDefault(size = 2)로 조정을 한다음에 실행하면
두 개씩 끊어서 나오는 걸 알 수 있다. 이제 화면에서 페이징을 구현할 차례이다.
bootstrap에서 페이징 처리하는 코드를 가져와 붙여 넣기 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
|
cs |
이제 해야할 것은 1. 현재 페이지 앞 뒤로 4칸씩 보이기 2. 현재 페이지에 'active'하기 3. 페이지 버튼 클릭 시 해당 페이지로 화면 이동하기
1번
만약 현재 페이지가 5번에 있다면 앞 뒤로 4칸씩 보여야 하니까[ 1 2 3 4 '5' 6 7 8 9 10 ]이렇게 보여야 한다. 하지만 만약 페이지가 6번까지만 있다면 10번이 아니라 마지막 페이지는 6번이 되어야 한다.
controller
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@GetMapping("/board/list")
public String boardList(@PageableDefault(size = 2) Pageable pageable, Model model) {
Page<Board> boards = boardService.getBoardList(pageable);
int startPage = boards.getPageable().getPageNumber() - 4;
int endPage = boards.getPageable().getPageNumber() + 4;
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("list", boards);
return "board/boardList";
}
|
cs |
우선 boards.getPageable().getPageNumber()는 현재 페이지를 나타내기 때문에 시작페이지는 현재 페이지에서 -4, 끝페이지는 현재 페이지에서 +4를 해준다.
1
2
3
4
5
6
7
8
9
10
11
|
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li class="page-item" th:each="num : ${#numbers.sequence(startPage, endPage)}">
<a class="page-link" href="#" th:text="${num}">1</a></li> <li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
|
cs |
controller에서 전달한 startPage와 endPage를 each문을 통해서 반복하며 출력해준다.
그러면 이런식으로 뜨는데 그 이유는 현재 페이지가 1에서 -4를 하게 된다면 음수로 나오기 때문이다.
그래서 startPage는 최솟값이 1, endPage는 최댓값이 페이지의 마지막으로 정해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@GetMapping("/board/list")
public String boardList(@PageableDefault(size = 2) Pageable pageable, Model model) {
Page<Board> boards = boardService.getBoardList(pageable);
int startPage = Math.max(1, boards.getPageable().getPageNumber() - 4);
int endPage = Math.min(boards.getPageable().getPageNumber()+4, boards.getTotalPages());
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
model.addAttribute("list", boards);
return "board/boardList";
}
|
cs |
size = 2로 하고 게시글을 10개 넣으면 위 사진과 같이 페이지가 1~4페이지만 보이는 걸 알 수 있다.
2번
1
2
3
4
5
6
7
8
9
10
11
|
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item" th:classappend="${startPage == list.pageable.pageNumber + 1} ? 'disabled'">
<a class="page-link" href="#" tabindex="-1">Previous</a>
</li>
<li class="page-item" th:classappend="${num == list.pageable.pageNumber + 1} ? 'active'" th:each="num : ${#numbers.sequence(startPage, endPage)}">
<a class="page-link" href="#" th:text="${num}">1</a></li> <li class="page-item" th:classappend="${endapge == list.pageable.pageNumber + 1} ? 'disabled'">
<a class="page-link" href="#">Next</a>
</li>
</ul>
</nav>
|
cs |
list.pageable.pageNumber는 controller에서 boards.getPageable(). getPageNumber()와 같기 때문에 현재 페이지를 뜻한다.
그래서 현재페이지 에서 1을 더한 것과 같은 숫자의 페이제 버튼에 active를 표시해 준다.
그래서 /board/list?page=0일 때 버튼 1이 active 된다.
3번 (버튼 클릭시 페이지 이동)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item" th:classappend="${startPage == list.pageable.pageNumber + 1} ? 'disabled'">
<a class="page-link" th:href="@{/board/list(page=${list.pageable.pageNumber - 1})}" tabindex="-1">Previous</a>
</li>
<li class="page-item" th:classappend="${num == list.pageable.pageNumber + 1} ? 'active'" th:each="num : ${#numbers.sequence(startPage, endPage)}">
<a class="page-link" th:href="@{/board/list(page=${num-1})}" th:text="${num}">1</a></li>
<li class="page-item" th:classappend="${endPage == list.pageable.pageNumber + 1} ? 'disabled'">
<a class="page-link" th:href="@{/board/list(page=${list.pageable.pageNumber + 1})}">Next</a>
</li>
</ul>
</nav>
|
cs |
th:href에서 (page=..)는 파라미터를 뜻한다.
그래서 num-1로 해서 경로를 지정해 주면 페이징 구현이 완료된다.
출처
www.youtube.com/watch?v=hmSPJHtZyp4
'게시판' 카테고리의 다른 글
[SPRING BOOT_JPA] JPA계층형 댓글 구현해보기-1 (2) | 2021.02.19 |
---|---|
[SPRING BOOT_JPA] DB를 통해 파일 업로드 및 다운로드 하기 (0) | 2021.02.06 |
[SPRING BOOT_JPA] Multipartfile로 이미지 저장하기 (0) | 2021.02.05 |