안녕하세요?
MelonPeach입니다.
이전에 게시판을 다듬는 과정을 포스팅했었는데요.
이번에는 게시판의 페이징을 구현하도록하겠습니다.
페이징은 글 목록의 갯수를 제한하는 것인데요.
글 목록에 글이 50개가 있다면 50개가 다보여지면 스크롤을 많이 내려야하겠지요..
그렇기 때문에 페이징을 구현하여 한 페이지에 글이 10개가 보여지는 작업을 하려고합니다.
1.더미용 데이터 쌓기
이 쿼리는 더미용 데이터를 만들기 위한 쿼리인데요.
현재 데이터가 3개가 있다면 이쿼리를 실행하면 6개, 그리고 1번더 실행하면 12개 이렇게
계속 데이터가 쌓이는 쿼리입니다. 데이터를 만드신후 commit도 해줍니다.
insert into mp_board(bno, title, content, writer)
select mp_board_seq.nextval, title, content, writer from mp_board;
commit;
2.게시글 10개씩 출력 쿼리
이 쿼리는 from절에서 rNum으로 약칭한 row_number()에 번호를 매깁니다. 번호는 내림차순이며,
이렇게 조회된 from절 데이터로 다시 select 조회를 합니다.
조건은 rNum이 1~10까지 그리고 내림차순으로 조회한다는 뜻입니다.
3.boardMapper.xml 코드 수정
boardMapper.xml에서 list쿼리를 사진과 같이 수정해 줍니다. list -> listPage
<select id="listPage" resultType="kr.co.vo.BoardVO" parameterType="kr.co.vo.Criteria">
SELECT BNO,
TITLE,
CONTENT,
WRITER,
REGDATE
FROM (
SELECT BNO,
TITLE,
CONTENT,
WRITER,
REGDATE,
ROW_NUMBER() OVER(ORDER BY BNO DESC) AS RNUM
FROM MP_BOARD
) MP
WHERE RNUM BETWEEN #{rowStart} AND #{rowEnd}
ORDER BY BNO DESC
</select>
4.Criteria.java 파일 추가
kr.co.vo 패키지에 Criteria.java 파일을 추가해주고 코드를 추가해줍니다.
package kr.co.vo;
public class Criteria {
private int page;
private int perPageNum;
private int rowStart;
private int rowEnd;
public Criteria() {
this.page = 1;
this.perPageNum = 10;
}
public void setPage(int page) {
if (page <= 0) {
this.page = 1;
return;
}
this.page = page;
}
public void setPerPageNum(int perPageNum) {
if (perPageNum <= 0 || perPageNum > 100) {
this.perPageNum = 10;
return;
}
this.perPageNum = perPageNum;
}
public int getPage() {
return page;
}
public int getPageStart() {
return (this.page - 1) * perPageNum;
}
public int getPerPageNum() {
return this.perPageNum;
}
public int getRowStart() {
rowStart = ((page - 1) * perPageNum) + 1;
return rowStart;
}
public int getRowEnd() {
rowEnd = rowStart + perPageNum - 1;
return rowEnd;
}
@Override
public String toString() {
return "Criteria [page=" + page + ", perPageNum=" + perPageNum + ", rowStart=" + rowStart + ", rowEnd=" + rowEnd
+ "]";
}
}
5.DAO, Service.java 파일 수정
원래 있던 게시물 목록 조회에 코드를 수정해주고, 게시물 총 갯수 코드를 추가해줍니다.
6.BoardMapper.xml 수정
게시물 총 갯수도 추가해주었으니 BoardMapper.xml에 코드를 추가해줍니다.
<select id="listCount" resultType="int">
<![CDATA[
SELECT COUNT(BNO)
FROM MP_BOARD
WHERE BNO > 0
]]>
</select>
7.BoardController.java 수정
BoardController.java에 코드를 수정해줍니다. Criteria에서 만든것을 쓰기 위함이죠.
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(Model model, Criteria cri) throws Exception{
logger.info("list");
model.addAttribute("list", service.list(cri));
return "board/list";
}
8.PageMaker.java 파일 추가
kr.co.vo에 PageMaker.java파일을 추가해줍니다.
package kr.co.vo;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
public class PageMaker {
private int totalCount;
private int startPage;
private int endPage;
private boolean prev;
private boolean next;
private int displayPageNum = 10;
private Criteria cri;
public void setCri(Criteria cri) {
this.cri = cri;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
calcData();
}
public int getTotalCount() {
return totalCount;
}
public int getStartPage() {
return startPage;
}
public int getEndPage() {
return endPage;
}
public boolean isPrev() {
return prev;
}
public boolean isNext() {
return next;
}
public int getDisplayPageNum() {
return displayPageNum;
}
public Criteria getCri() {
return cri;
}
private void calcData() {
endPage = (int) (Math.ceil(cri.getPage() / (double)displayPageNum) * displayPageNum);
startPage = (endPage - displayPageNum) + 1;
int tempEndPage = (int) (Math.ceil(totalCount / (double)cri.getPerPageNum()));
if (endPage > tempEndPage) {
endPage = tempEndPage;
}
prev = startPage == 1 ? false : true;
next = endPage * cri.getPerPageNum() >= totalCount ? false : true;
}
public String makeQuery(int page) {
UriComponents uriComponents =
UriComponentsBuilder.newInstance()
.queryParam("page", page)
.queryParam("perPageNum", cri.getPerPageNum())
.build();
return uriComponents.toUriString();
}
}
9.BoardController.java 코드 수정
PageMaker를 만들었으니 적용시킵니다.
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(Model model, Criteria cri) throws Exception{
logger.info("list");
model.addAttribute("list", service.list(cri));
PageMaker pageMaker = new PageMaker();
pageMaker.setCri(cri);
pageMaker.setTotalCount(service.listCount());
model.addAttribute("pageMaker", pageMaker);
return "board/list";
}
10.list.jap 코드 수정
list.jsp에 코드를 추가해줍니다.
<div>
<ul>
<c:if test="${pageMaker.prev}">
<li><a href="list${pageMaker.makeQuery(pageMaker.startPage - 1)}">이전</a></li>
</c:if>
<c:forEach begin="${pageMaker.startPage}" end="${pageMaker.endPage}" var="idx">
<li><a href="list${pageMaker.makeQuery(idx)}">${idx}</a></li>
</c:forEach>
<c:if test="${pageMaker.next && pageMaker.endPage > 0}">
<li><a href="list${pageMaker.makeQuery(pageMaker.endPage + 1)}">다음</a></li>
</c:if>
</ul>
</div>
11.<li>태그 가로로 정렬
페이징을 가로로 정렬해주는 스타일입니다.
<style type="text/css">
li {list-style: none; float: left; padding: 6px;}
</style>
12. 테스트
페이징이 잘나오는것을 확인하실 수 있습니다.
다음 포스팅은 검색해서 조회할 수 있는 기능에 대해 포스팅 하겠습니다.