페이징 만들기
다른 사람 코드 적용하려고 해도 내가 사용하고 있는 개발 환경에 딱 알맞거나 중간에 필요한 부분이 빠져있어 직접 만들어서 다 적어보았다.
개발 환경
1. Spring Boot
2. Mybatis
3. Mysql
4. thymeleaf
PaginationVo
import lombok.Data;
@Data
public class PaginationVo {
/*
* 주석에 사용된 단어 정의
* 페이지: 화면 아래에 위치하는 특정 페이지를 지칭하는 숫자
* 인덱스: 특정 페이지에서 특정 게시물을 지시하는 숫자
*/
int rowCount = 5; // 한 페이지 당 보여줄 게시물 개수
int pageCount = 3; // 한 블럭에 몇 개의 페이지 개수
int totalCount; // 총 게시물 개수
int page; // 현재 페이지
int startPage = 1; // 한 블럭의 시작 페이지: 기본 값 1 // ex) 1 2 3 4 5 일 때 1을 의미.
int endPage; // 한 블럭의 끝 페이지
int totalPageCount; // 총 페이지 개수
boolean isPrev = false; // 다음 페이지로 이동하는 버튼 유무
boolean isNext = false; // 이전 페이지로 이동하는 버튼 유무
int offset; // 얼만큼 끊어서 가져올 것인가.
public PaginationVo(final int totalCount, final int page) {
// 총 페이지 개수 구하기
setTotalPageCount(totalCount, this.rowCount);
// 한 블럭의 첫 페이지 구하기
setStartPage(this.startPage, page, this.pageCount);
// 한 블럭의 끝 페이지 구하기
setEndpage(this.startPage, this.pageCount, this.totalPageCount);
// 이전 블록 버튼 유무 판별하기
isPrev(page, this.pageCount);
// 다음 블록 버튼 유무 판별하기
isNext(this.endPage, this.totalPageCount);
// offset 구하기
setOffset(page, this.rowCount);
}
// 총 페이지 개수 구하기
private void setTotalPageCount(final int totalCount, final int rowCount) {
this.totalPageCount = (int) Math.ceil(totalCount * 1.0 / rowCount);
}
// 한 블럭의 첫 페이지 구하기
private void setStartPage(final int startPage, final int page, final int pageCount) {
this.startPage = startPage + (((page - startPage) / pageCount) * pageCount);
}
// 한 블럭의 끝 페이지 구하기
private void setEndpage(final int startPage, final int pageCount, final int totalPageCount) {
this.endPage = ((startPage - 1) + pageCount) < totalPageCount ? (startPage - 1) + pageCount : totalPageCount;
}
// 이전 블럭으로 이동할 버튼 생성 유무
private void isPrev(final int page, final int pageCount) {
this.isPrev = 1 < ((page * 1.0) / pageCount);
}
// 다음 블럭으로 이동할 버튼 생성 유무
private void isNext(final int endPage, final int totalPageCount) {
this.isNext = endPage < totalPageCount;
}
// offset 구하기 // 쿼리 select 시 끊어서 가져오기
private void setOffset(final int page, final int rowCount) {
this.offset = (page - 1) * rowCount;
}
}
Controller
@GetMapping("/board")
public String selectListAndPage(final Model model, @RequestParam(value = "page",
defaultValue = "1") final int page) {
PaginationVo paginationVo = new PaginationVo(this.boardService.getCount(), page); // 모든 게시글 개수 구하기.
List<Board> list = this.boardService.getListPage(paginationVo);
model.addAttribute("boardList", list);
model.addAttribute("page", page);
model.addAttribute("pageVo", paginationVo);
return "board";
}
Service
// 페이징을 위한 전체 데이터 개수 파악
public int getCount() {
return this.boardMapper.getCount();
}
// 페이징을 위한 getListPage 메소드 추가
public List<Board> getListPage(final PaginationVo paginationVo) {
return this.boardMapper.getListPage(paginationVo);
}
HTML
<div id="pagination">
<!-- 맨 처음 페이지로 이동하는 버튼 -->
<span th:if="${pageVo.startPage > 1}">
<a th:href="@{'/board?page=1'}" th:text="'처음 '"></a>
</span>
<!-- 이전 블록으로 이동하는 버튼 -->
<span th:if="${pageVo.isPrev == true}">
<a th:href="@{'/board?page='+${pageVo.startPage - 1}}" th:text="'이전'"></a>
</span>
<!-- 시퀀스 보여주는 값을 변경. -->
<span th:each="pageNum : ${#numbers.sequence(pageVo.startPage, pageVo.endPage)}">
<a class="div2" th:href="@{'/board?page='+${pageNum}}" th:text="| ${pageNum} |"></a>
</span>
<!-- 다음 블록으로 이동하는 버튼 -->
<span th:if="${pageVo.isNext == true}">
<a th:href="@{'/board?page='+|${pageVo.endPage + 1}|}" th:text="'다음'"></a>
</span>
<!-- 맨 뒷 페이지로 이동하는 버튼 -->
<span th:if="${pageVo.endPage < pageVo.totalPageCount}">
<a th:href="@{'/board?page='+${pageVo.totalPageCount}}" th:text="| 끝|"></a>
</span>
</div>
SQL
<!-- 게시물 총 개수 구하기 -->
<select id="getCount" resultType="int">
SELECT count(*) as listCnt
FROM board
</select>
<select id="getListPage" parameterType="com.test.board.dto.PaginationVo" resultType="com.test.board.dto.Board">
SELECT *
FROM board
ORDER BY id DESC
LIMIT #{rowCount}
OFFSET #{offset}
</select>
LIMIT : 해당 수 만큼 개수 제한한다.
OFFSET : 해당 수 만큼 건너뛰고 시작한다.
결과