스프링부트 게시판 페이지네이션/검색바 구현

https://rebornbb./entry/Springboot-%EA%B2%8C%EC%8B%9C%ED%8C%90%EB%94%B0%EB%9D%BC%ED%95%98 %EA%B8%B08-%EA%B2%80%EC%83%89-%EA%B8%B0%EB%8A%A5-%E2%9C%94%EC%A0%95%EB%A6% 에어컨

참고로 페이지네이션과 검색창을 구현했습니다.

페이징 관련 기능을 따로 모으기 위해 별도의 paginationService를 생성하고 바 길이도 서비스에 포함한다.

  • 페이징 서비스
@Service
public class PaginationService {
    private static final int BAR_LENGTH=5;
    
    public int getPaginationBarStartNumber(int currentPage, int totalPage){
        int startPage= Math.max(currentPage-BAR_LENGTH/2,1);
        return startPage;
    }

    public int getPaginationEndStartNumber(int startPage, int totalPage){
        int endPage=Math.min(startPage+BAR_LENGTH,totalPage);
        return endPage;
    }

}

  • 기사 컨트롤러
@GetMapping
public String SearchArticles(
        @PageableDefault(size = 10, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable,
        ModelMap map,
        String searchKeyword
){
    Page<Article> searchArticles =null;
    if(searchKeyword==null){ //검색을 하지 않았을 경우
        searchArticles=articleService.searchArticle(pageable);

    }else{
        searchArticles = articleService.searchArticles(searchKeyword,pageable);
    }

    int totalPage=searchArticles.getTotalPages();
    int nowPage = searchArticles.getPageable().getPageNumber() + 1; //pageable에서 넘어온 현재페이지를 가지고올수있다 * 0부터시작하니까 +1
    int startPage=paginationService.getPaginationBarStartNumber(nowPage,totalPage);
    int endPage=paginationService.getPaginationEndStartNumber(startPage,totalPage);

    map.addAttribute("searchArticles",searchArticles);
    map.addAttribute("nowPage", nowPage);
    map.addAttribute("startPage", startPage);
    map.addAttribute("endPage", endPage);


    return "articles/articleList";

}

  • 기사/articleList.html
<!
DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{layouts/default_layout}"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div layout:fragment="content"> <main class="container"> <table> <thead> <th>글 번호</th> <th>제목</th> <th>내용</th> </thead> <tbody> <tr th:each="article : ${searchArticles}"> <td th:text="${article.id}"></td> <td> <a th:href="http://duck-cow./m/@{/articles/{articleId}(articleId=${article.id})}" th:text="${article.title}">제목 </a> </td> <td th:text="${article.content}"></td> </tr> <form th:action="@{/articles/form}" th:method="get"> <button type="submit" th:text="'게시글 작성'"></button> </form> <form th:action="@{/logout}" method="post"> <button type="submit" th:text="'로그아웃'"></button> </form> </tbody> </table> </main> <!
--굳이 태그로 감쌀필요가없는 부분을 타임리프 문법을 사용할때 쓰는 문법 th:block--> <th:block th:each= "page : ${#numbers.sequence(startPage, endPage)}"> <!
--검색기능-4--> <a th:if="${page !
= nowPage}" th:href="@{/articles(page = ${page -1}, searchKeyword = ${param.searchKeyword})}" th:text="${page}"> </a> <strong th:if="${page == nowPage}" th:text="${page}" style="color : red"></strong> </th:block> <form th:action="@{/articles}" method="get"> <input type="text" name="searchKeyword"> <button type="submit">검색</button> </form> </div> </body> </html>