package kr.or.ddit.vo;
import java.util.List;
import lombok.Data;
@Data
public class PaginationInfoVO<T> {
private int totalRecord; // 총 게시글 수
private int totalPage; // 총 페이지 수
private int currentPage; // 현재 페이지
private int screenSize; // 페이지 당 게시글 수
private int blockSize; // 페이지 블록 수
private int startRow; // 시작 row
private int endRow; // 끝 row
private int startPage; // 시작 페이지
private int endPage; // 끝 페이지
private List<T> dataList; // 결과를 넣을 데이터 리스트
private String searchType; // 검색 타입
private String searchWord; // 검색 단어(키워드)
public PaginationInfoVO() {}
// PaginationInfoVO 객체를 만들 때, 한 페이지당 게시글 수와 페이지 블록 수를 원하는 값으로 초기화 할 수 있다.
public PaginationInfoVO(int screenSize, int blockSize) {
this.screenSize = screenSize;
this.blockSize = blockSize;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
// ceil은 올림
// totalRecord = 121
// 121 / 10 = 12.1
// 올림을 통해서 13을 만들고 정수로 만든다. (totalPage)
totalPage = (int)Math.ceil(totalRecord / (double)screenSize);
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage; // 현재 페이지
endRow = currentPage * screenSize; // 끝 row = 현재페이지 * 한 페이지당 게시글 수
startRow = endRow - (screenSize -1); // 시작 row = 끝 row - (한 페이지당 게시글 수 - 1)
// 마지막 페이지 = (현재페이지 + (페이지 블록 사이즈 -1 )) / 페이지 블록 사이즈 * 페이지 블록 사이즈
// /blockSize * blockSize는 1,2,3,4,5 ... 페이지마다 실수계산이 아닌 정수 계산을 이용해 endPage를 구하기 위함
endPage = (currentPage + (blockSize -1)) / blockSize * blockSize;
startPage = endPage - (blockSize-1);
}
public String getPagingHTML() {
// startPage는 1,6,11 ... 등으로 해당 숫자의 형태로 증가해서 올라갑니다.
// 1-5 범위 안에 있는 경우는 Prev가 생성되지 않는다.
// 6범위부터 Prev가 만들어지는 조건이 생성된다.
StringBuffer html = new StringBuffer();
html.append("<ul class='pagination pagination-sm m-0 float-right'>");
if(startPage > 1) {
html.append("<li class='page-item'><a href='' class='page-link' data-page='"+
(startPage - blockSize) + "'>Prev</a></li>");
}
for(int i= startPage; i<= (endPage< totalPage ? endPage : totalPage); i++) {
if(i == currentPage) {
html.append("<li class='page-item active'><span class='page-link'>" + i + "</span></li>");
}else {
html.append("<li class='page-item'><a href='' class='page-link' data-page='" +
i+ "'>" + i + "</a></li>");
}
}
if(endPage < totalPage) {
html.append("<li class='page-item'><a href='' class='page-link' data-page='" +
(endPage+1) + "'>Next</a></li>");
}
html.append("</ul>");
return html.toString();
}
}
screenSize = 10개 (페이지 당 게시물 수)
blockSize = 5개 (하단 페이징 블록 수)
totalRecord = 131개 (총 게시글 수)
totalPage = 131 / 10 = 13.1 > 14개 (올림처리)
currentPage = 4페이지 (내가 현재 있는 페이징 블록위치)
해당페이지의 시작게시물순번과 끝게시물순번 31~40
endRow 4x10 =40
startRow 40-(10-9) = 31
endPage 4+(5-1) = 8 / 5x5 = 8
< 4 5 6 7 8 >
startPage 8- 4 = 4
sql 쿼리
select
b.*
from(
select
a.*, row_number() over(order by a.bo_no desc) rnum
from(
select
bo_no, bo_title, bo_content, bo_writer, bo_date, bo_hit
from board
where 1=1
order by bo_no desc
)a
)b
where b.rnum >= 1 and b.rnum <= 10;
endRow와 startRow를 적용한 spring 쿼리
<select id="selectBoardList" parameterType="paginationInfoVO" resultType="boardVO">
select
b.*
from(
select
a.*, row_number() over(order by a.bo_no desc) rnum
from(
select
bo_no, bo_title, bo_content, bo_writer, bo_date, bo_hit
from board
where 1=1
order by bo_no desc
)a
)b
<![CDATA[
where b.rnum >= #{startRow} and b.rnum <= #{endRow}
]]>
</select>