-
[ Spring Boot + JPA + Thymeleaf ] 페이징 기능 구현Spring Boot 2021. 3. 4. 21:24
Pageable
Pageable은 Spring에서 페이징 기능을 위한 파라미터들을 추상화 시킨 인터페이스이다.
(인터페이스 자체는 매우 간단하고 메서드명도 직관적이기 때문에 소스를 까보는 것도 좋다)
이 Pageable을 아래와 같이 Controller의 RequestMapping 메서드 인자로 넣을 수 있다.1. Controller
- BoardController.java
@Controller @RequestMapping("/board") public class BoardController { @Autowired private BoardRepository boardRepository; @Autowired private BoardValidator boardValidator; // 리스트 출력 @GetMapping("/list") public String list(Model model, @PageableDefault(size = 2) Pageable pageable, @RequestParam(required = false, defaultValue = "") String searchText){ //Page<Board> boards = boardRepository.findAll(pageable); Page<Board> boards = boardRepository.findByTitleContainingOrContentContaining(searchText,searchText,pageable); int startPage = Math.max(1,boards.getPageable().getPageNumber() - 4); int endPage = Math.min(boards.getTotalPages(),boards.getPageable().getPageNumber() + 4); model.addAttribute("startPage",startPage); model.addAttribute("endPage",endPage); model.addAttribute("boards", boards); return "board/list"; } }
- Pageable 객체를 생성하기 위해서 사용되는 요청 파라미터
- page : 가져올 페이지 (기본값 : 0)
- size : 페이지의 크기 (기본값 : 20)
- sort : 정렬 기준으로 사용할 속성으로 기본적으로 오름차순으로 한다. 정렬 기준 속성이 2개 이상인 경우에는 sort 파라미터를 2개 이상 넣어주면된다. 예) sort=firstname&sort=lastname,asc.
Pageable 파라미터에 @PageableDefault 어노테이션을 사용하면 디폴트 값을 변경할 수 있다.
위의 코드를 보면 우선 페이징 처리하기위해 인자로 pagealbe를 넣어주었다. 페이지 디폴트 사이즈는 우선 size=2로 주었고. 한 화면에 페이지 리스트가 4개씩 보여지게 하기 위해서 보여지는 시작페이지와 마지막페이지를 계산해주기 위해
현재 페이지에서 각각 -4,+4를 하였다 만약 현재 페이지가 4보다 작다면 마이너스값이 나올 수 있기때문에 Math.max()를 이용하여 계산결과 값이 마이너스일때는 1이 뽑히도록 해주었고 마지막 페이지에도 똑같은 방법으로 처리해주었다.
이제 가공된 데이터를 가지고 화면에 표시를 해볼 것이다.
2. View
- list.html
<!doctype html> <html xmlns:th="http://www.thymelef.org"> <head th:replace="fragments/common :: head('게시판')"> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('list')"> </nav> <div class="container"> <h2>게시판</h2> <div>총 건수 : <span th:text="${boards.totalElements}"></span></div> <form class="row g-3 align-items-center d-flex justify-content-end" method="GET" th:action="@{/board/list}"> <div class="col-auto"> <label for="searchText" class="col-form-label">검색</label> </div> <div class="col-auto"> <input type="text" id="searchText" class="form-control" name="searchText" th:value="${param.searchText}"> </div> <div class="col-auto"> <button type="submit" class="btn btn-light">검색</button> </div> </form> <table class="table"> <thead> <tr> <th scope="col">번호</th> <th scope="col">제목</th> </tr> </thead> <tbody> <tr th:each="board : ${boards}"> <th th:text="${board.id}">1</th> <td><a th:text="${board.title}" th:href="@{/board/form(id=${board.id})}" >Mark</a></td> </tr> </tbody> </table> <nav aria-label="Page navigation example"> <ul class="pagination"> <li class="page-item" th:classappend="${1 == boards.pageable.pageNumber+1} ? 'disabled' "> <a class="page-link" href="#" th:href="@{/board/list(page=${boards.pageable.pageNumber-1},searchText=${param.searchText})}">Previous</a> </li> <li class="page-item" th:classappend="${i == boards.pageable.pageNumber+1} ? 'disabled' " th:each="i : ${#numbers.sequence(startPage,endPage)}"> <a class="page-link" href="#" th:text="${i}" th:href="@{/board/list(page=${i-1},searchText=${param.searchText})}">1</a> </li> <li class="page-item" th:classappend="${boards.totalPages == boards.pageable.pageNumber+1} ? 'disabled' "> <a class="page-link" href="#" th:href="@{/board/list(page=${boards.pageable.pageNumber+1},searchText=${param.searchText})}">Next</a> </li> </ul> </nav> <div class="text-right"> <a type="button" class="btn btn-primary" th:href="@{/board/form}">글쓰기</a> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> </body> </html>
boards.pageable.pageNumber의 값은 인덱스 값이 넘어와서 +1을 해주어 계산해주었고, 만약 첫 페이지의 경우 Previous버튼을 비활성화 시켜주었다. 마찬가지로 Next버튼도 동일하게 처리해주었고. 각 버튼을 클릭했을때 파라미터를 이용하여 이동 페이지값을 넘겨주었다. 이때도 마찬가지로 페이지표현상 +1 처리가 되어있기때문에 컨트롤러에서는 인덱스값으로 계산되어야 하므로 -1해주어 값을 넘겨주어야한다.
'Spring Boot' 카테고리의 다른 글
[ Spring Boot + JPA + Thymeleaf ] 댓글 기능 구현 (0) 2021.03.18 [ Spring Boot + JPA + Thymeleaf ] 검색 기능 구현 (0) 2021.03.04 [ Spring Boot + JPA + Thymeleaf ] validation 추가 (0) 2021.03.02 [ Spring Boot + JPA + Thymeleaf ] 로그인/회원가입 (0) 2021.02.23 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 3 (0) 2021.02.10