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>
결과화면
'👩🏻💻 About 프로그래밍 > spring' 카테고리의 다른 글
AOP (0) | 2024.09.09 |
---|---|
IoC(Inversion of Control) · DI(Dependency Injection) (3) | 2024.09.03 |
Spring Data JPA Entity 연관관계 (0) | 2024.08.13 |
Spring boot 게시판 댓글 CRUD (0) | 2024.08.13 |
Spring boot 게시판 만들기(게시판 CRUD) (0) | 2024.08.13 |
블로그의 정보
Hello 춘기's world
볼빵빵오춘기