외국어 직독직해하듯 코드 독해하기
목표
1. 게시판 List에서 기본 페이지네이션 구현하기 [1]
2. 원래 있던 페이지 번호로 돌아가기 [2]
- 게시글 상세에서 [목록]버튼 눌렀을 때
- 게시글 수정 후 [목록]버튼 눌렀을 때
- 게시글 삭제 후
게시판 List에서 페이지네이션 활성화시키기
Criteria.java -- 페이지네이션 출력 기본 설정 관리
public class Criteria {
private int page; // 현재 페이지 번호
private int postsPerPage; // 한 페이지 당 게시글 수
//Criteria 디폴트 생성자
public Criteria() {
this.page = 1; // 현재 페이지를 1페이지로 설정
this.postsPerPage = 10; // 한 페이지 당 게시글 수 10개로 설정
}
//getter and setter
public int getPage() {
return page;
}
public void setPage(int page) {
if(page <= 0) { // 현재 페이지 번호가 음수라면,
this.page = 1; // 페이지 번호 1로 설정
}
else
this.page = page;
}
public int getPostsPerPage() {
return postsPerPage;
}
public void setPostsPerPage(int postsPerPage) {
if(postsPerPage <=0 || postsPerPage > 100) { // 페이지 당 게시글 수가 0개 이하거나 100개를 초과할 때
this.postsPerPage = 10; // 페이지 당 게시글 수를 10개로 설정.
}
else
this.postsPerPage = postsPerPage;
}
@Override
//Criteria 정보 콘솔 출력 메서드
public String toString() {
return "Criteria [page=" + page + ", postsPerPage=" + postsPerPage + "]";
}
//쿼리문에서 limit에 사용되는 인덱스를 계산하는 getter
public int getPageStart() {
return (this.page -1) * postsPerPage;
}
}
마지막 getter -- getPageStart()는 아래 BoardMapper.xml에서 활용되니 거기서 설명.
PageMaker.java -- 페이지네이션 출력 상세 설정 관리
import lombok.Data;
@Data
public class PageMaker {
private int totalCount; // 총 게시글 수
private int startPage; // 시작 번호
private int endPage; // 끝 번호
private boolean prev; // 이전 버튼 유무
private boolean next; // 다음 버튼 유무
private int displayPageNum; // 페이지네이션 한 세트에 보여질 페이지번호 갯수
private Criteria criteria; // 페이지네이션 기본 설정 정보
//endPage, startPage, prev, next 값을 계산하는 메서드
public void calcData() {
endPage = (int) (Math.ceil(criteria.getPage()/(double) displayPageNum)*displayPageNum);
//endPage = (int)(Math.ceil(3/(double)10) * 10)
startPage = (endPage - displayPageNum)+1;
//총 게시글 개수를 이용하여 제일 마지막 페이지 번호를 계산
int theLastPage = (int)(Math.ceil(totalCount/(double)criteria.getPostsPerPage()));
if(endPage > theLastPage) {
endPage = theLastPage;
}
//현재 페이지가 1페이지면 이전(prev)버튼이 없어야 함
prev = startPage == 1 ? false : true;
//현재 페이지에 마지막 게시글이 포함되어 있으면 다음(next)버튼이 없어야 함
next = endPage * criteria.getPostsPerPage() >= totalCount ? false:true;
}
}
EX ) 현재 페이지가 13페이지이고, 페이지네이션 한 세트에 보여지는 페이지 번호 수가 10일 때
==> startPage = 11 , endPage = 20 이어야 함.
- endPage의 계산 : (int) (Math.ceil(criteria.getPage()/(double) displayPageNum)*displayPageNum);
Math.ceil() : 소수점 올림. (현재 실수와 같거나 큰 정수를 반환)
endPage = (13/10.0)*10 => 1.3*10 => 2*20 => 20 - startPage의 계산 : (endPage - displayPageNum)+1;
startPage = (20 - 10)+1 => 11
결과 : prev 11 12 13 14 15 16 17 18 19 20 next
EX) 총 게시글 수가 223개이고, 한 페이지 당 게시글 수가 10개일 때
- 페이지네이션의 맨~~~마지막 페이지 계산 : (int)(Math.ceil(totalCount/(double)criteria.getPostsPerPage()));
theLastPage = (223/10.0) => 6.2 => 23
결과 : prev 21 22 23
BoardController.java -- 게시글 리스트 출력 컨트롤러
@GetMapping("/noticeBoard/noticeList")
public ModelAndView noticeBoardListGet(ModelAndView mv, Criteria cri) { // 매개변수 Criteria cri 를 추가.
cri.setPostsPerPage(5); // 한 페이지당 보여질 게시글 개수 설정
PageMaker pm = new PageMaker(); // PageMaker 객체 생성
pm.setCriteria(cri); // cri 정보를 pm의 Criteria에 담기.
pm.setDisplayPageNum(2); // 페이지네이션 한 세트에 보여지는 페이지 번호의 개수를 설정
int totalCount = boardService.getTotalCount(cri); // 게시글 총 개수 구하기
pm.setTotalCount(totalCount); // pm의 TotalCount에 위에서 구한 게시글 총 개수 설정하기
pm.calcData(); // endPage, startPage, prev/next 버튼 노출 여부 설정하는 메서드 실행
ArrayList<PostVO> list = boardService.getBoardList(cri);
mv.addObject("list", list);
mv.addObject("pm", pm); // pm정보를 "pm"에 담아 jsp에 전달
mv.setViewName("/template/board/noticeBoard/noticeList");
return mv;
}
- noticeBoardListGet -- Controller의 매개변수에 Criteria cri 를 추가
- 한 페이지당 게시글 5개씩, 페이지네이션 한 세트당 2개 페이지가 설정되도록 작성 됨.
- addObject로 pm객체 정보를 전달.
BoardService.java
ArrayList<PostVO> getBoardList(Criteria cri); // 매개변수 Criteria cri 추가
int getTotalCount(Criteria cri);
- getBoardList - Service에 Criteria cri 추가.
- getTotalCount - Service 생성.
BoardServiceImp.java
@Override
public ArrayList<PostVO> getBoardList(Criteria cri) { // 매개변수 Criteria cri 추가
return boardDao.getBoardList(cri); // cri 추가
}
@Override
public int getTotalCount(Criteria cri) {
return boardDao.getTotalCount(cri);
}
- getBoardList - ServiceImp에 Criteria cri 추가.
- getTotalCount - ServiceImp 생성.
BoardDAO.java
ArrayList<PostVO> getBoardList(@Param("cri") Criteria cri); // 매개변수 Criteria cri 추가
int getTotalCount(@Param("cri") Criteria cri);
- getBoardList - DAO에 Criteria cri 추가.
- getTotalCount - DAO 생성.
BoardMapper.xml -- 게시판의 게시글을 불러오는 쿼리문 수정
<select id="getBoardList" resultType="com.ysy.bakingdom.vo.PostVO">
select * from post where post_state = '1' order by post_num desc
<!-- 불러올 게시글 개수 설정 -->
limit #{cri.pageStart}, #{cri.postsPerPage}
</select>
- limit #{cri.pageStart}, #{cri.postsPerPage} : 전체 데이터 값에서 "pageStart+1부터 postsPerPage까지" 불러옴
cri.pageStart : Critera.java 에 있는 인덱스 계산 getter의 리턴 값 => return (this.page -1) * postsPerPage;
EX) 만약 한 페이지당 게시글 수가 3개 라고 가정하면,
BoardMapper.xml -- 전체 게시글 수를 구하는 쿼리문 작성
<select id="getTotalCount" resultType="int">
select count(*) from post where post_state = '1'
</select>
<nav aria-label="Page navigation example">
<ul class="pagination d-flex justify-content-center">
<!-- 이전 버튼 눌렀을 때 -->
<c:if test="${pm.prev}">
<li class="page-item">
<a class="page-link" href="<%=request.getContextPath()%>/noticeBoard/noticeList?page=${pm.startPage-1}" aria-label="Previous">
<span aria-hidden="true">«</span> <!-- « = "<<" -->
</a>
</li>
</c:if>
<!-- 페이지 번호를 눌렀을 때 -->
<c:forEach begin="${pm.startPage}" end="${pm.endPage}" var="index">
<li class="page-item <c:if test="${pm.criteria.page == index}">active</c:if>">
<a class="page-link" href="<%=request.getContextPath()%>/noticeBoard/noticeList?page=${index}">${index}</a></li>
</c:forEach>
<!-- 다음 버튼 눌렀을 때 -->
<c:if test="${pm.next}">
<li class="page-item">
<a class="page-link" href="<%=request.getContextPath()%>/noticeBoard/noticeList?page=${pm.endPage+1}" aria-label="Next">
<span aria-hidden="true">»</span> <!-- » = ">>" -->
</a>
</li>
</c:if>
</ul>
</nav>
- <c:if test="${ [pm.prev | pm.next] }"> </c:if>
- [pm.prev | pm.next] 가 ture이면 [ 이전 | 다음 ] 버튼 활성화. - <c:forEach begin="${pm.startPage}" end="${pm.endPage}" var="index">
- begin(시작페이지) 부터 end(끝페이지)까지 (PageMaker.java 참고) 를 반복문으로 변수 "index"에 담고, 쭉 출력(나열)한다. - 현재 페이지 번호와 index가 같은 페이지네이션 번호는 active(파란 색 표시)를 활성화 시킨다.
작업완료 결과
http://localhost:8080/noticeBoard/noticeList
페이지네이션 한 세트에 2개의 페이지가 설정되고, 한 페이지 당 게시글 5개씩 보여짐.
여기까지가 기본 페이지네이션 구현이다.
다음 포스트는..
2. 원래 있던 페이지 번호로 돌아가기
- 게시글 상세에서 [목록]버튼 눌렀을 때
- 게시글 수정 후 [목록]버튼 눌렀을 때
- 게시글 삭제 후
를 작성해보겠다. (힘들당..)
'SPRING > 연습장' 카테고리의 다른 글
jQuery Validation Plugin 검사 후, submit전 alert 띄우기 (0) | 2021.09.16 |
---|---|
게시판 페이징 처리 (pagination) [2] - 원래 있던 페이지 번호로 돌아가기 (0) | 2021.08.29 |
Interceptor 동작 경로 설정 (0) | 2021.08.24 |
form안의 데이터를 한 번에 묶어 ajax로 전송하기 (0) | 2021.08.17 |
session과 cookie를 이용한 자동 로그인 기능 (0) | 2021.08.17 |