Paging 구현하기
- 전자정부프레임워크
- 2018. 2. 28. 15:36
이번엔 Paging 을 구현 해보자.
페이징을 구현하기 위해선
먼저 페이징 VO가 필요하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | public class CmmnVO { private static final long serialVersionUID = 1L; /*rows : 현재 페이지에 보여질 row수 page : 현재 보여질 페이지 수 totalPage : 총 페이지 수 startPage : 시작페이지수 endPage : 끝 페이지 수 pageScale : 한 페이지에 보여질 페이지 수*/ private long rows = 2; private long page = 1; private long totalPage; private long startPage = 1; private long endPage; private long pageScale = 3; public long getRows() { return rows; } public void setRows(long rows) { this.rows = rows; } public long getPage() { return page; } public void setPage(long page) { this.page = page; } public long getTotalPage() { return totalPage; } public void setTotalPage(long totalPage) { this.totalPage = totalPage; } public long getStartPage() { return startPage; } public void setStartPage(long startPage) { this.startPage = startPage; } public long getEndPage() { return endPage; } public void setEndPage(long endPage) { this.endPage = endPage; } public long getPageScale() { return pageScale; } public void setPageScale(long pageScale) { this.pageScale = pageScale; } } | cs |
위와같이 6개의 필드가 들어간다. 그리고 이 VO를 상속받는
VO를 만들어줘야한다 CmmnVO는 공통으로 빼놓은것이다
왜냐하면 각 페이지마다 페이징이 다를수 있기 때문이다.
따라서 다른 VO객체를 생성해 CmmnVO를 상속받아
사용하면된다.
1 2 3 | package egovframework.example.welcomeWeb.service; public class PagingVO extends CmmnVO { } | cs |
이제 sql-mapper-config에 VO들을
alias 해주자.
다음 가장 중요한 마이바티스쪽의 쿼리문을 보자
첫번째 쿼리이다
<select id="selectPagingList" parameterType="pagingVO" resultType="egovMap">
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SELECT a.* FROM ( SELECT a.*, ROWNUM rnum, FLOOR((ROWNUM - 1) /#{rows} + 1) pageNumber FROM ( SELECT ID, USER_NAME, AGE, COUNTRY, ETC FROM welcome_web ORDER BY ID ASC ) a ) a WHERE a.pageNumber = #{page} order by a.rnum | cs |
${rows} 는 전달할 페이지의 줄 숫자이다 PagingVO로 넘겨서 받는다.
예를 들어서 2번째 줄은 페이지 넘버가 1이다
CmmnVO에서 rows에 2값을 주었기 때문에
(2-1)/3+1 = 1이 된다 FLOOR은 버림을 담당한다.
그래서 첫째 줄은 1 둘째줄도1 셋째줄은 2 넷째줄도2
이렇게 된다.
그리고 16line 에서 #page를 가져온다. 이것은 어떤
페이지가 눌렸는지에 따라 조건을 주는것이다.
이값 또한 CmmnVO에 설정되어있다.
다음 두번째 쿼리문이다
<select id="selectPagingListCnt" parameterType="pagingVO" resultType="egovMap">
1 2 3 4 5 | SELECT count(*) TOTAL_TOT_CNT , CEIL(count(*) / #{rows}) TOTAL_PAGE FROM welcome_web WHERE 1=1 ORDER BY ID ASC | cs |
위의 쿼리문은 토탈 카운트이다. 즉 게시판으로 따지면
전체 게시글의 갯수를 구한다. 그리고
전체 페이지를 구한다.
CEIL은 올림함수이다.
페이징의 쿼리는 2개가 필요하다 진짜값들을 가져오는 쿼리와
갯수 파악을 위한 쿼리이다.
다음 컨트롤러로 가자.
1 2 3 4 5 6 7 | @RequestMapping(value = "welcomeWeb5.do") public String initMain0(PagingVO pagingVo ,ModelMap model) throws Exception { List<Map> PagingList = welcomeWebService.selectPagingList(pagingVo); EgovMap pagingListCnt = welcomeWebService.selectPagingListCnt(pagingVo); HashMap<String, Object> resMap = new HashMap<String, Object>(); | cs |
PagingVO 객체를 사용한다.
다음 HashMap에 로직들을 put 해준다.
1 2 3 | resMap.put("total", pagingListCnt.get("totalPage")); resMap.put("page", pagingVo.getPage()); resMap.put("pageScale", pagingVo.getPageScale()); | cs |
먼저 sql에서 구한 토탈페이지를 put해주고
VO안에 설정한 page와 pageScale를 put해준다
1 2 3 4 5 6 7 | int pageGroup = (int)Math.ceil((double)pagingVo.getPage()/pagingVo.getPageScale()); long startPage = (pageGroup - 1) * pagingVo.getPageScale() + 1; pagingVo.setStartPage(startPage); long endPage = startPage + pagingVo.getPageScale() - 1; pagingVo.setEndPage(endPage); | cs |
다음 페이지 그룹을 정의한다.
페이지 그룹은 특정페이지가 어떤 그룹에 속해있는지 알아야한다.
예를 들어 게시글 밑의 페이지번호를 3개씩 보여주고 싶다면
1,2,3 후에 다음 버튼을 누르면 4,5,6이 나와야한다.
이제 여기서 1,2,3 페이지는 1그룹이고 4,5,6페이지는 2그룹이 되는것이다.
다음 시작 페이지와 끝페이지를 set 해준다
처음 화면에서 시작페이지는 1페이지 이다
하지만 다음 버튼을 눌러 2그룹의 페이지를 보게되면
4페이지가 시작 페이지가 되어야한다.
끝 페이지또한 시작페이지와 같은 원리이다.
1 2 | long prePage = (pageGroup - 2) * pagingVo.getPageScale() + 1; long nextPage = pageGroup * pagingVo.getPageScale() + 1; | cs |
이전페이지와 다음페이지이다.
이전 페이지는 페이지그룹이 1일땐 이전페이지가
표시되면 않된다 이를 jsp에서 if문을주어 걸러줘야한다.
구분을 위해 첫번째 그룹은 음수가 나오게 된다
이제 만든 값들을 Map 으로 put해주고
1 2 3 4 5 | resMap.put("startPage", pagingVo.getStartPage()); resMap.put("endPage", pagingVo.getEndPage()); resMap.put("nextPage", nextPage); resMap.put("prePage", prePage); resMap.put("pageGroup", pageGroup); | cs |
1 2 | model.addAttribute("PagingList", PagingList); model.addAttribute("resMap", resMap); | cs |
값들을 뷰로 보내주면된다
다음 jsp를 보자
1 2 3 4 5 | <c:if test="${resMap.pageGroup > 1}"> <li> <a href="javascript:fnGoPaging(<c:out value='${resMap.prePage}' /> )">≪</a> </li> </c:if> | cs |
첫페이지 에서는 이전 버튼이 없어야 되므로
1line 에서 if문을 주어 걸러준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <c:forEach var="i" begin="${resMap.startPage}" end="${resMap.endPage > resMap.total ? resMap.total : resMap.endPage}" varStatus="status"> <c:choose> <c:when test="${resMap.page eq i}"> <li class="active"> <a href="javascript:fnGoPaging(${i});">${i}</a> </li> </c:when> <c:otherwise> <li> <a href="javascript:fnGoPaging(${i});">${i}</a> </li> </c:otherwise> </c:choose> </c:forEach> | cs |
로직을 보면 각 페이지가 눌려 1,2,3 이 나오고 4가 나오게된다.
1,2,3 중 어떤 것을 누르던 토탈페이지는 4이다.
그래서 반복문을 3번 돌게된다
3line 에서 진짜 눌린 페이지와 i를 비교하여
일치하게되면 active를 주게 되는데 이것은 그냥 부트스트랩에서
눌린페이지를 표시해주는것이다.
1 2 3 4 5 | <c:if test="${resMap.nextPage <= resMap.total}"> <li> <a href="javascript:fnGoPaging(<c:out value='${resMap.nextPage}'/>)">≫</a> </li> </c:if> | cs |
다음버튼이다.
1 2 3 | function fnGoPaging(page) { location.href = "http://localhost:8081/sample/welcomeWeb5.do?page="+page; } | cs |
마지막으로 스크립트단 안에
위와 같이 fnGoPaging 함수를 넣어준다.
?page로 파라미터 page를 넘긴다
즉 컨트롤러로 page값이 넘어가게 된다.
'전자정부프레임워크' 카테고리의 다른 글
jQgrid 사용하기 (5) | 2018.03.01 |
---|---|
한글처리 하기 (0) | 2018.02.28 |
체크박스 사용해 원하는 값 출력하기 (0) | 2018.02.27 |
체크박스 값 확인하기 (0) | 2018.02.27 |
@RequestParam 과 String로 값 주고 받기 (0) | 2018.02.26 |