페이징 준비물
현재 페이지 번호 = pageNum
페이지마다 띄워줄 게시글 갯수 = amount
(화면에 뜨는 페이지 번호 중에서) 맨 앞 페이지 번호 = startPage
(화면에 뜨는 페이지 번호 중에서) 맨뒤 페이지 번호 = endPage
이전 페이지 존재 유무 = prev
다음 페이지 존재 유무 = next
전체 게시글 수 = total
1.페이지(pageNum)마다 일정량(amount)의 게시글을 가져오는 쿼리 작성
예를 들어, 글을 10개씩 띄워준다고 할 때 4페이지를 받았으면
서브쿼리문에서는 (4*10)1~40번째 글을 select하고,
그 40개의 글중에서 (3*10)1~30번째 글을 제외한 31~40번째 글을 내림차순으로 select해줌!
<select id="getListWithPaging" resultType="com.wine.model.NoticeVO">
<![CDATA[
select noticeno, subject, id, indate, count
from(select /*+INDEX_DESC(notice SYS_C007844)*/
rownum rn, noticeno, subject, id, indate, count
from notice
where rownum<= #{pageNum} * #{amount})
where rn > (#{pageNum}-1) * #{amount}
]]>
</select>
2. 전체 게시글 수(total) 구하는 쿼리 작성
<select id="pageTotal" resultType="int">
select count(*) from notice where noticeno > 0
</select>
3. 1.에서의 쿼리문에 쓰이는 조건값을 담을 Criteria(DTO) 클래스 생성
@Data
public class Criteria {
private int pageNum;
private int amount;
private int prodno;
public Criteria() {
this(1,5);
}
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
}
4. view에 전달해줄 값을 담을 PageDTO 클래스 생성
@Data
public class PageDTO {
//맨처음 페이지 번호
private int startPage;
//맨끝 페이지 번호
private int endPage;
//이전 페이지, 다음 페이지 (있으면 true)
private boolean prev, next;
//전체 게시글 번호
private int total;
//현재 페이지 번호, 띄워줄 글 갯수
private Criteria cri;
public PageDTO(Criteria cri, int total) {
this.cri = cri;
this.total = total;
//현재 페이지 번호를 올림처리해서 마지막 번호를 지정
//ex.현재 페이지가 12페이지면 1.2(ceil)=>2에서 다시 10을 곱해 마지막 페이지는 20으로 정해짐.
//수정함 => 6페이지면 0.6이 1로되고 다시 5를 곱해서 5
this.endPage=(int)(Math.ceil(cri.getPageNum()/5.0))*5;
//시작 페이지
//ex. 20(마지막페이지)-9= 11로 시작하게 됨.
this.startPage = this.endPage-4;
//마지막에 뿌려질 페이지번호(더이상 띄워줄 글이 없을 때는 번호가 멈춰야하니까)
//ex. 전체 글이 253개이고, 한 페이지당 10글씩 띄워준다고 했을 때 253.0에 10을 나누면 25.3이고 올림하면 26
int realEnd = (int)(Math.ceil((total*1.0)/cri.getAmount()));
//마지막 페이지(예를들면 30일때)가 찐마지막 페이지(26)보다 크면 페이지 바꿔줌
if(realEnd <this.endPage) {
this.endPage = realEnd;
}
//이전 페이지는 시작 번호보다 크다.
this.prev = this.startPage > 1;
//다음 페이지는 찐마지막페이지보다 작다.
this.next = this.endPage < realEnd;
}
}
5. interface NoticeMapper
public List<NoticeVO> getListWithPaging(Criteria cri);
public int pageTotal(Criteria cri);
6.NoticeServiceImpl implements NoticeService
@Override
public List<NoticeVO> getList(Criteria cri) {
return mapper.getListWithPaging(cri);
}
@Override
public int getTotal(Criteria cri) {
return mapper.pageTotal(cri);
}
7.NoticeController
@RequestMapping("/notice")
public void notice(Criteria cri, Model model) {
model.addAttribute("noticeList", nService.getList(cri)); //게시글 값
int total = nService.getTotal(cri);
model.addAttribute("pageMaker", new PageDTO(cri,total,1));//페이징 값
}
8.notice.jsp
<!-- 현재 11~20페이지라고 가정했을 때 -->
<!-- 이전 페이지가 있으면 10페이지로 이동 (1~10페이지로 바꿔줌) -->
<c:if test="${pageMaker.prev}">
<a href="${pageMaker.startPage -1}">이전</a>
</c:if>
<!-- 11번부터 20번까지 num을 뿌려줌. 현재페이지(pageNum)은 class 붙여줌 -->
<c:forEach var="num" begin="${pageMaker.startPage}" end="${pageMaker.endPage}">
<a href="${num}"><span class="${pageMaker.cri.pageNum == num ? 'bold':''}"> ${num} </span></a>
</c:forEach>
<!-- 다음 페이지가 있으면 21페이지로 이동 (21~30페이지로 바꿔줌) -->
<c:if test="${pageMaker.next}">
<a href="${pageMaker.endPage +1}">다음</a>
</c:if>
8-1.값을 넘겨주기 위해 페이지에 저장해둔다.
<form id='actionForm' action="/notice/notice" method='get'>
<input type='hidden' name='pageNum' value='${pageMaker.cri.pageNum}'>
<input type='hidden' name='amount' value='${pageMaker.cri.amount}'>
</form>
<script>
$(document).ready(function(){
var actionForm = $('#actionForm');
$("#pageBtn a").on("click",function(e){
e.preventDefault();
actionForm.find("input[name='pageNum']").val($(this).attr("href"));
actionForm.submit();
});
});
</script>
'Git · 코드 기록' 카테고리의 다른 글
Git 설치 버전 릴리스 스태시 (모두의 깃&깃허브_강민철 지음) (0) | 2022.11.13 |
---|---|
Spring 게시판 좋아요 기능 구현 (0) | 2022.11.12 |
Spring 게시판 댓글 기능 구현 (0) | 2022.11.07 |
파일 업로드 처리 (0) | 2022.11.03 |
제품 추천 기능 구현하기 (0) | 2022.10.23 |