티스토리 뷰
※ 페이징 처리를 위해서 필요한 정보
• 현제 페이지 번호(page)
• 이전과 다음으로 이동 가능한 링크의 표시여부(prev, next)
• 화면에서 보여지는 페이지의 시작 번호와 끝번호(startPage, endPage)
• 제일 끝번호(realEnd)
끝번호 (endPage)
현재 페이지의 번호를 알아야 하는 이유는 페이지의 시작 번호와 끝번호를 알아야 하기 때문입니다.
페이지가 5개씩 나눠 떨어진다고 할때
3페이지를 보고 있을 때의 화면의 보여지는 시작페이지와 끝페이지는 1, 5일 것이고
7페이지를 보고 있을 때의 화면의 보여지는 시작과 끝페이지는 6, 10일 것입니다.
이는 끝페이지만 구할수 있으면 첫페이지는 구하기 쉽기 때문에 끝페이지부터 구한다면
아래와 같은 공식으로 구할 수 있습니다.
this.endPage = (int) (Math.ceil(페이지 번호/5.0))*5;
ceil메서드는 소수점이 있기만 하면 올림으로 처리하기 때문에
Math.ceil( 1 페이지 = 0.2 ) = 1
Math.ceil( 2 페이지 = 0.4 ) = 1
Math.ceil( 3 페이지 = 0.6 ) = 1
Math.ceil( 4 페이지 = 0.8 ) = 1
Math.ceil( 5 페이지 = 1.0 ) = 1 로 되기 때문에 1~5페이지의 마지막 번호는 5가 됩니다.
Math.ceil( 6 페이지 = 1.2 ) = 2 로 되기 때문에 6~10페이지의 마지막 번호는 10이 됩니다.
시작번호 (startPage)
시작 번호는 끝번호를 알면 바로 알수 있습니다.
5로 나뉘기 때문에 끝번호 -4만 해주면 시작번호를 알수가 있습니다.
this.startPage = this.endPage - 4;
1~5페이지의 마지막번호 5(endPage) - 4 = 1(startPage)
6~10페이지의 마지막번호 10(endPage) - 4 = 6(startPage)
제일 끝번호(realEnd)
끝번호는 현재 내가 보고있는 페이지 기준의 끝번호고 게시물의 가장 끝번호를 구해주어야 합니다.
그렇지 않으면 게시물은 14번째에서 끝나지만 15번의 끝번호가 생기기 때문입니다.
제일 끝번호는 (총 게시물갯수 / 한 페이지 게시물 갯수) 를 반올림한 수로 제일 끝번호를 알 수 있습니다.
realend = (int) Math.ceil((total * 1.0)/amount);
총 게시물이 89개 일때
89*1.0=89.0
89.0/10=8.9
ceil(8.9)=9
9페이지가 최종 페이지 입니다.
이렇게 되면 문제가 하나 생기는데 최종페이지는 9페이지이지만 끝번호는 10으로 끝나도록 설정했었습니다.
이렇게 끝번호보다 최종 페이지가 작을 경우에는 끝번호가 최종페이지가 되어야 합니다.
if(realend < this.endPage){
this.endPage = realend;
}
이렇게 설정해주면 최종페이지가 끝번호보다 작다면 끝번호는 최종페이지로 될것입니다.
이전과 다음 (prev, next)
이전버튼은 시작번호가 1보다 큰경우에 존재 할 수 있습니다.
this.prev = this.startPage > 1;
다음 버튼은 끝번호가 최종번호보다 작을 경우에만 존재 할 수 있습니다.
this.next = this.endPage < realend;
위와 같은 정보를 클래스를 구성해서 처리하면
PageDTO클래스 작성
package com.startcoriny.domain;
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()/5.0))*5; // pagenum이 5를 넘어가지 않으면 ceil함수로 인해 1/5=0.2, 2/5=0.4 ...5/5=1 모두가 1이기 때문에 1*5=5, 페이지를 옮겨도 끝번호 10번의 숫자로 넘어가지 않음.
System.out.println("@@@@@@@this.endPage = " + this.endPage);// 5..10..15..20..25
this.startPage = this.endPage - 4; // 1..6..11..16..21
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;
}
}
위 Criteria 클래스에서 초기화한 pageNum과 amount를 가져와서 계산에 활용할 수 있습니다.
jsp에서 사용 하기 위해선 controller의 model에 담아 화면에 전달해야합니다.
BoardController 클래스작성
package com.startcoriny.controller;
@Controller
@RequestMapping("/board/*")
public class BoardController {
private BoardService service;
// 게시물 리스트
@GetMapping("/list")
public void list(Criteria cri, Model model) {
int total = service.getTotal(cri);
model.addAttribute("list",service.getList(cri));
model.addAttribute("pageMaker", new PageDTO(cri, total));
}
}
controller에서 게시물 목록의 대한 데이터와 paging에 대한 정보들도 model에 담아서 jsp에 넘겨 줍니다.
부트스트랩을 사용한 jsp
<!-- start Pagination -->
<div class="pull-right">
<ul class="pagination">
<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="paginate_button next">
<a href="${pageMaker.endPage +1 }">Next</a>
</li>
</c:if>
</ul>
</div>
<!-- end Pagination -->
표현 언어와 커스텀 태그를 사용하여 데이터를 전달해 준다.
또한 위 jsp코드에서는 a링크로 전달되는것은 단순 숫자 임으로 해당 게시판 페이지로 이동을 하지 않기 때문에
form 태그로 데이터를 보낼 경로와 데이터를 전달해야합니다.
<form action="/board/list" id="actionForm" method="get">
<input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum }"> <!-- 자바스크립트에서 동적으로 바뀌도록 설정했으므로 value생략 가능 -->
<input type="hidden" name="amount" value="${pageMaker.cri.amount }"> <!-- 자바스크립트에서 pageNum은 다루므로 생략 가능하지만 amount는 다루지않으므로 value 초기값 필요 -->
</form>
그리고 a링크를 클릭했을 때 아래의 form태그를 동작 시켜야 하므로 JavaScript를 사용 합니다.
JavaScript
<script type="text/javascript">
$(document).ready(function(){
var actionForm = $("#actionForm");
$(".paginate_button a").on("click", function(e){
e.preventDefault();
console.log('click');
actionForm.find("input[name='pageNum']").val($(this).attr("href"));
actionForm.submit();
});
});
</script>
이렇게 작동을 시키면
https: /board/list?pageNum=해당페이지번호&amount=지정해둔 페이지당 게시물 갯수
위 url 처럼 쿼리문자열로 서버에 데이터를 보낼수 있습니다.
배워나가는 코린이 입니다!!
부족한게 있다면 댓글로 지적해주세요!! 감사합니다!😊
'프로그래밍 기초 > Spring' 카테고리의 다른 글
게시판 페이징 처리(1) (2) | 2023.12.15 |
---|---|
한글 깨짐 현상 해결 (0) | 2023.11.30 |
프로젝트 절대 경로 설정 (0) | 2023.11.30 |
의존성 주입이란? (0) | 2023.11.23 |