코드로 배우는 스프링 웹 프로젝트를 보고 작성
페이징 처리를 위해 필요한 파라미터
1) 페이지 번호(pageNum)
2) 한 페이지 당 몇 개의 데이터(amount)
Criteria.java : 페이징 처리를 위해 필요한 파라미터를 객체로 묶어서 전달한다. (SQL에서 계산과 연관)
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Criteria {
private int pageNum;
private int amount;
public Criteria(){
this(1,10);
}
public Criteria(int pageNum, int amount){
this.pageNum = pageNum;
this.amount = amount;
}
}
생성자로 기본 1페이지, 10개씩 설정해준다.
BoardMapper.xml
<select id="getListWithPaging" resultType="org.zerock.domain.BoardVO">
<![CDATA[
select
bno, title, content, writer, regdate, updatedate
from
(
select /*+INDEX_DESC(tbl_board pk_board)*/
rownum rn, bno, title, content, writer, regdate, updatedate
from
tbl_board
where rownum <= #{pageNum} * #{amount}
)
where rn > (#{pageNum} -1) * #{amount}
]]>
</select>
페이징 화면 처리
보통 게시판으로 가정하면 목록 페이지, 조회페이지, 수정 삭제 페이지까지 페이지 번호가 계속해서 유지되어야 한다.
화면 페이징을 하기 위해서 필요한 정보
- 현재 페이지 번호(page)
- 이전과 다음으로 이동 가능한 링크의 표시 여부(prev, next)
- 화면에 보여지는 페이지의 시작 번호와 끝 번호
페이징의 끝 번호(endPage) 계산
this.endPage = (int)(Math.ceil(페이지번호 / 10.0)) * 10;
여기서 페이지 번호(page)란 현재 사용자가 보고 있는 페이지를 의미한다.
this.endPage = (int)(Math.ceil(페이지번호/countPage)) * countPage;
Math.ceil()은 소수점을 올림으로 처리한다.
1페이지의 경우 : Math.ceil(0.1) * 10 = 10
10페이지의 경우 : Math.ceil(1) * 10 = 10
11페이지의 경우 : Math.ceil(1.1) * 10 = 20
페이징의 시작 번호(startPage) 계산
this.startPage = this.endPage - 9;
화면을 10개씩 보여준다고 가정했을 때 이렇게 계산하는 것이므로 (countPage - 1) -> countPage란 한 화면에 출력될 게시물의 개수를 의미.
이렇게 countPage를 받아서 계산하면 유동적으로 페이징을 변경할 수 있을 것 같아서 코드를 추가했다.
this.startPgae = this.endPage - (countPage - 1);
끝 번호(endPage)는 다시 계산되어야 한다.
생각해보면 10페이지씩 countPage 된다고 할 때, 총 220개의 게시물이 있다고 가정 22페이지가 끝 번호이다.
그러나 저 계산식대로 계산하면(현재 페이지 21이라고 가정) Math.ceil(21 / 10.0) * 10 = 30페이지
30페이지가 끝번호라고 나온다. 30page != 22page 인 것이다.
방법은 간단하다.
전체 데이터 수(total)을 가지고 끝 페이지를 조정하면 된다.
realEnd = Math.ceil((총 게시글 * 1.0) / 10(countPage));
if(realEnd < this.endPage){
this.endPage = realEnd;
}
이전(prev), 다음(next)
이전(prev) 계산
this.prev = this.startPage > 1;
시작 페이지가 1이 넘는다면 이전 버튼이 생성되어야 한다.!
다음(next) 계산
this.next = this.endPage < realEnd;
다음도 마찬가지로 realEnd(총 게시글 가지고 구한 마지막 페이지)가 계산된 마지막 페이지보다 작으면
다음 버튼이 활성화 되어야 한다.
(이해하기 어려울 수도 있다. 헷갈렸다)
페이징 처리를 위한 클래스 설계
PageDTO
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public class PageDTO{
private int startPage;
private int endPage;
private boolean prev, next;
private int total;
private Criteria cri;
public PageDTO(Criteria cri, int total){
this.cri = cri;
this.total = total;
this.endPage = (int)(Math.ceil(cri.getPageNum() / 10.0)) * 10;
this.startPage = this.endPage - 9;
int realEnd = (int)(Math.ceil((total * 1.0) / cri.getAmount()));
if(realEnd < this.endPage){
this.endPage = realEnd;
}
this.prev = this.startPage > 1;
this.next = this.endPage < realEnd;
}
}
JSP에서 페이지 번호 출력
<div class='pull-right'>
<ul class="pagination">
<c:if test="${pageMaker.prev}">
<li class="paginate_button previous">
<a href="#">Previous</a>
</li>
</c:if>
<c:forEach var="num" begin="${pageMaker.startPage}" end="${pageMaker.endPage}">
<li class="paginate_button">
<a href="#">${num}</a>
</li>
</c:forEach>
<c:if test="${pageMaker.next}">
<li class="pagenate_button next">
<a href="#">Next</a>
</li>
</c:if>
</ul>
</div>
페이지 번호 이벤트 처리
<c:if test="${pageMaker.prev}">
<li class="paginate_button previous">
<a href="${pageMaker.startPage - 1}">Previous</a>
</li>
</c:if>
<c:forEach var="num" begin="${pageMaker.startPage}" end="${pageMaker.endPage}">
<li class="paginate_button ${pageMaker.cri.pageNum == num ? "active":""}">
<a href="${num}">${num}</a>
</li>
</c:forEach>
<c:if test="${pageMaker.next}">
<li class="pagenate_button next">
<a href="${pageMaker.endPage + 1}">Next</a>
</li>
</c:if>
<form id="actionForm" action="/board/list" method='get'>
<input type='hidden' name='pageNum', value='${pageMaker.cri.pageNum}'/>
<input type='hidden' name='amount', value='${pageMaker.cri.amount}'/>
</form>
$(document).ready(function(){
var result = '<c:out value="${result}">';
checkModal(result);
history.replaceState({}, null, null);
function checkModal(result){
if(result === '' || history.state){
return;
}
if(parseInt(result) > 0){
$(".modal-body").html("게시글 " + parseInt(result) + " 번이 등록되었습니다.);
}
$("#myModal").modal("show");
}
$("#regBtn").on("click", function(){
self.location = "/board/register";
});
var actionForm = $("actionForm");
$(".paginate_button a")on("click", function(e){
m.preventDefault();
console.log('click');
actionForm.find("input[name='pageNum']").val$(this).attr("href"));
actionForm.submit();
});
});
'CS지식들 > 공부공부' 카테고리의 다른 글
동시성 문제 (3) (0) | 2022.12.19 |
---|---|
동시성 문제 (2) (0) | 2022.12.19 |
동시성 문제 (1) (0) | 2022.12.18 |
JPA에서 페이징/정렬 처리하기 (0) | 2022.11.30 |
페이징 처리 (오라클) (0) | 2022.11.29 |