Hello

Spring boot 게시판 목록 페이징(feat. JPA)

by 볼빵빵오춘기

게시판에서 페이징 처리를 하지않고 리스트를 보여지게 되면 모든 데이터를 한 번에 가져오기 때문에 가져와야할 데이터가 적은 양이면 문제가 되지않지만 가독성이 떨어질 뿐만아니라 많은 리스트를 가져오게 된다면 서버와 데이터베이스에 부하가 되며, 로딩 시간도 길어지므로 페이징 처리를 했다.

 

Controller

코드 설명

  • @PageableDefault를 이용하여 구현하였다.
  • @PageableDefault을 이용하지 않고 Repository에서 List타입으로 가져올 수도 있지만 @PageableDefault을 사용함으로써 페이징처리에 정렬기준, 페이징의 사이즈 등 각각 구현하지않고 가져올 수 있다. 
@GetMapping("/communityL")
public String list(Model model, @PageableDefault(page = 0, size = 15,sort = "id",direction = Sort.Direction.DESC) Pageable pageable, String searchKeyword){
    Page<CommunityEntity> list = null;
		
    if(searchKeyword == null) { // 검색어가 없을 경우
        list = commnunityService.list(pageable);
    }else { // 검색어가 있을 경우
        list = commnunityService.searchList(searchKeyword, pageable);
    }

		// 페이징 처리에 필요
    int nowPage = list.getPageable().getPageNumber() + 1; // 현재 페이지를 알려주는 숫자
    int startPage = Math.max(nowPage - 4, 1); // 페이지가 시작되는 페이지 숫자
    int endPage = Math.min(nowPage + 5, list.getTotalPages()); // 페이지의 마지막 페이지의 숫자

    model.addAttribute("list", list);
    model.addAttribute("nowPage", nowPage);
    model.addAttribute("startPage", startPage);
    model.addAttribute("endPage", endPage);

    return "community/list";
}

 

@PageableDefault

  • Spring Data JPA에서 페이징을 처리할 때 기본값을 설정하는 데 사용되는 어노테이션이다.
  • 클라이언트가 페이지 요청을 하지 않은 경우에도 기본적인 페이징 및 정렬 설정을 적용할 수 있다.

 

@PageableDefault 속성

  • page
    • 기본 페이지 번호를 설정한다.
    • 인덱스는 0부터 시작한다.
    • @PageableDefault(page = 0)는 첫 번째 페이지를 의미한다.

 

  • size
    • 한 페이지에 포함될 기본 항목 수를 설정한다.
    • @PageableDefault(size = 15)는 한 페이지에 15개의 항목을 포함한다는 의미이다.

 

  • sort
    • 정렬 기준 필드를 설정한다.
    • @PageableDefault(sort = "id")는 id 필드를 기준으로 정렬한다.

 

  • direction
    • 정렬 방향을 설정한다.
    • Sort.Direction.ASC는 오름차순, Sort.Direction.DESC는 내림차순 정렬을 의미한다. @PageableDefault(direction = Sort.Direction.DESC)는 내림차순 정렬을 의미한다.

 

Service

  • Page<T> 을 타입으로 지정하면, 파라미터에 Pageable을 받아야한다.
  • Spring Data JPA에서 findAll() 메소드를 사용하였다.
public Page<CommunityEntity> list(Pageable pageable){
    return commnunityRepository.findAll(pageable);
}

 

HTML

리스트

controller에서 model에 담겨온 list를 tymeleaf에 th:each를 사용하여 리스트를 보여준다.

<div class="col-12 mb-15">
    <table class="list-group">
        <th>
            <tr class="list-group-item list-group-item-action active">
                <th>no</th>
                <th >제목</th>
            </tr>
        </th>
        <tbody>
            <tr th:each="board: ${list}" class="list-group-item list-group-item-action">
                <td th:text="${board.id}"></td>
                <td >
                    <a th:text="${board.title}" th:href="@{${'/communityV/'+board.id}}"></a>
                </td>
            </tr>
        </tbody>
    </table>
    <div th:if="${endPage == 0}" class="text-center">
        등록되어있는 글이 없습니다.
    </div>
</div>

 

페이징

paging 처리에서 th:if를 넣어 현재 페이지와 페이지 숫자가 같으면 비활성화, 현재 페이지와 페이징의 나타나는 숫자가 다르면 링크를 걸어 넘어가도록 처리하였다.

<div class="col-12 mb-30">

    <div class="d-flex justify-content-center" th:if="${endPage > 0}">
        <ul class="pagination">
        <th:block th:each="page : ${#numbers.sequence(startPage, endPage)}">
            <li class="page-item">
                <a class="page-link" th:if="${page != nowPage}" th:href="@{/communityL(page = ${page - 1}, searchKeyword = ${param.searchKeyword})}" th:text="${page}"></a>
                <strong class="page-link" th:if="${page == nowPage}" th:text="${page}" style="color : red" ></strong>
            </li>
        </th:block>
        </ul>
    </div>


    <form th:action="@{/communityL}" method="get" class="c-searchForm d-flex">
        <input type="text" name="searchKeyword" placeholder="제목으로 검색해보세요." class="width100p">
        <button type="submit" class="btn btn-primary" >검색</button>
    </form>
</div>

 

결과화면

 

블로그의 정보

Hello 춘기's world

볼빵빵오춘기

활동하기