본문 바로가기

게시판

[SPRING BOOT_JPA] 부트스트랩으로 페이징구현

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">
      <class="page-link" href="#" tabindex="-1">Previous</a>
    </li>
    <li class="page-item"><class="page-link" href="#">1</a></li>
    <li class="page-item"><class="page-link" href="#">2</a></li>
    <li class="page-item"><class="page-link" href="#">3</a></li>
    <li class="page-item">
      <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">
                <class="page-link" href="#" tabindex="-1">Previous</a>
            </li>
            <li class="page-item" th:each="num : ${#numbers.sequence(startPage, endPage)}">
<class="page-link" href="#" th:text="${num}">1</a></li>
            <li class="page-item">
                <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'">
                <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)}">
<class="page-link" href="#" th:text="${num}">1</a></li>
            <li class="page-item" th:classappend="${endapge == list.pageable.pageNumber + 1} ? 'disabled'">
                <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'">
                <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)}">
                <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'">
                <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