728x90
페이징 처리는 막상 해보니, 크게 어려움은 없었는데 변수가 많아서 헷갈렸다.
가장 중요한 변수는 세가지 정도이다.
총 게시물 (boards),
페이지 사이즈 (한 페이지에 담기는 게시물 수, pageSize),
총 페이지 수(총 게시물을 페이지사이즈로 나눈 수, totalPages)
기본적으로 페이지 사이즈는 10으로 잡는다. 나도 10으로 잡았다.
1. BoardController
// 게시판 글 조회 (페이징 처리 된)
@GetMapping
public String getAllBoards(Model model, @RequestParam(defaultValue = "1") int currentPage) {
int pageSize = 10; // 페이지당 게시물 수
List<BoardDto> boards = boardService.getBoardsByPage(currentPage, pageSize);
int totalPages = boardService.getTotalPages(pageSize);
model.addAttribute("boards", boards);
model.addAttribute("totalPages", totalPages);
model.addAttribute("currentPage", currentPage);
return "board";
}
2. BoardServiceImpl
// 페이지 별 게시판 글목록 조회
@Override
public List<BoardDto> getBoardsByPage(int currentPage, int pageSize) {
int offset = (currentPage - 1) * pageSize; // 현재 2페이지고 페이지사이즈가 10이면 offset은 10
Map<String, Integer> params = new HashMap<>();
params.put("pageSize", pageSize);
params.put("offset", offset);
return boardMapper.getBoardsByPage(params);
}
// 총 페이지 수 조회
@Override
public int getTotalPages(int pageSize) {
return boardMapper.getTotalPages(pageSize); // 총 게시물 수가 101이고, 페이지사이즈가 10이면 -> 총 페이지 수는 11
}
offset (현재까지 보여진 페이지 수) 를 사용했다.
boardMapper.getBoardsByPage(param) 이 메소드에는 map을 파라미터로 넣어주었다.
offset과 페이지사이즈를 넘겨주어 현재 보여줄 페이지 범위에 맞는 게시물을 불러오도록 했다.
예를 들어, offset이 10이고, 페이지사이즈가 10이면 매퍼가 불러올 페이지리스트는 11~20번의 게시물이 되는 것이다.
3. BoardMapper 인터페이스
// 페이지 별 게시판 글목록 조회
List<BoardDto> getBoardsByPage(Map<String, Integer> params);
// 총 페이지 수 조회
int getTotalPages(int pageSize);
4. BoardMapper.xml
<!-- 페이지 별 게시판 글목록 조회-->
<select id="getBoardsByPage" parameterType="map" resultType="com.example.first.dto.BoardDto" resultMap="boardResultMap">
SELECT *
FROM postgres.first_project.boards
ORDER BY created_at DESC
LIMIT #{pageSize} OFFSET #{offset};
</select>
<!-- 총 페이지 수 조회-->
<select id="getTotalPages" parameterType="int" resultType="int">
SELECT CEIL(COUNT(*)::NUMERIC / #{pageSize})
FROM postgres.first_project.boards;
</select>
총 페이지 수를 조회하는 쿼리에서는 CEIL을 사용하여 총 페이지 수가 올림처리 되도록 했다.
예를 들어,
총 게시글이 101개이고, 페이지사이즈가 10이면 101/10 으로 계산하여 10인데, 올림처리를 해서 11의 페이지 수가 반환되는 것이다.
5. board.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>게시판</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- Your custom styles -->
<style>
.center-title {
text-align: center;
}
.pagination {
margin: 20px auto;
}
.current-page {
border: 1px solid #ccc; /* 테두리 스타일 설정 */
box-shadow: 2px 2px 5px #888; /* 그림자 설정 */
padding: 5px 10px; /* 내부 여백 설정 */
border-radius: 5px; /* 모서리를 둥글게 만들기 위한 설정 */
}
</style>
</head>
<body>
<div class="container">
<!-- 마이페이지 버튼 -->
<div class="text-right mt-2">
<a href="/logout" class="btn btn-danger mr-2">로그아웃</a>
<a href="/mypage" class="btn btn-primary mr-2">마이페이지</a>
</div>
<br>
<h2 class="center-title">게시판</h2>
<!-- 글 작성 버튼 -->
<a href="/boards/create" class="btn btn-primary mb-3">글 작성</a>
<!-- 글 목록 -->
<table class="table">
<thead>
<tr>
<th scope="col" >제목</th>
<th scope="col">작성자</th>
<th scope="col">작성일</th>
</tr>
</thead>
<tbody>
<c:forEach items="${boards}" var="board">
<tr>
<td><a href="/boards/${board.boardId}">${board.title}</a></td>
<td>${board.nickname}</td>
<td>${board.createdAt}</td>
</tr>
</c:forEach>
</tbody>
</table>
<!-- 글 목록 아래 검색창 -->
<form action="/boards/search" method="GET" style="max-width: 300px; margin: 0 auto;">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="검색어를 입력하세요" name="keyword" aria-label="검색어" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-primary" type="submit">검색</button>
</div>
</div>
</form>
<br>
<br>
<!-- 페이징 처리 -->
<div class="text-center">
<ul class="pagination justify-content-center">
<li class="page-item">
<c:choose>
<c:when test="${currentPage > 1}">
<a class="page-link" href="/boards?currentPage=${currentPage - 1}">이전</a>
</c:when>
<c:otherwise>
<span class="page-link">이전</span>
</c:otherwise>
</c:choose>
</li>
<c:forEach begin="1" end="${totalPages}" var="pageNumber">
<li class="page-item">
<c:choose>
<c:when test="${pageNumber == currentPage}">
<span class="page-link current-page">${pageNumber}</span>
</c:when>
<c:otherwise>
<a class="page-link" href="/boards?currentPage=${pageNumber}">${pageNumber}</a>
</c:otherwise>
</c:choose>
</li>
</c:forEach>
<li class="page-item">
<c:choose>
<c:when test="${currentPage < totalPages}">
<a class="page-link" href="/boards?currentPage=${currentPage + 1}">다음</a>
</c:when>
<c:otherwise>
<span class="page-link">다음</span>
</c:otherwise>
</c:choose>
</li>
</ul>
</div>
</div>
<script>
</script>
</body>
</html>
페이징 처리가 잘 된다!
'Back-end > java' 카테고리의 다른 글
완전 간단하게 AOP로 log찍기 (0) | 2023.09.26 |
---|---|
빌드 중 NoSuchFileException 에러 미해결 (0) | 2023.09.26 |
파일 업로드 기능 구현 중 에러 - IllegalStateException: File has been moved - cannot be read again (0) | 2023.09.21 |
스프링 부트 페이징처리 (jsp, mybatis, postgresql) (0) | 2023.09.21 |
스프링부트 로컬에서 이미지 불러오기 (0) | 2023.09.19 |