본 내용은 혼자 공부하기 위하여 다른 포스트를 보면서 저에게 필요한 부분과 궁금했던 부분을 추가하여 게시하는 곳입니다.
궁금한 것에 대한 것은 모르는 것이 많겠지만 함께 알아보도록 노력하겠습니다.
참조 게시 포스트 : http://addio3305.tistory.com/
------------------------------------------------------------------------------------------------------------------------------------------
1. 설정
1.1. 전자정부 프레임워크 라이브러리
pom.xml
<repositories> <repository> <id>egovframe</id> <url>http://maven.egovframe.kr:8080/maven/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <dependency> <groupId>egovframework.rte</groupId> <artifactId>egovframework.rte.ptl.mvc</artifactId> <version>2.7.0</version> </dependency>
전자정부 프레임워크 라이브러리는 별도로 repository로 다운 받아야 하기 때문에 위와 같은 형식을 pom.xml에 추가하여 준다.
1.2 Bean 설정
context-common.xml
<bean id="textRenderer" class="egovframework.rte.ptl.mvc.tags.ui.pagination.DefaultPaginationRenderer"/> <bean id="paginationManager" class="egovframework.rte.ptl.mvc.tags.ui.pagination.DefaultPaginationManager"> <property name="rendererType"> <map> <entry key="text" value-ref="textRenderer"/> </map> </property> </bean>
전자정보 프레임워크의 페이지 렌더 방식 설정하는 부분으로 보다 자세한 설명은 해당 홈페이지에 있다.
(http://www.egovframe.org/wiki/doku.php?id=egovframework:rte:ptl:view:paginationtag)
1.3 SQL
sample_SQL.xml
<select id="sample.selectBoardList" resultType="hashmap" parameterType="hashmap" > <![CDATA[ SELECT ( SELECT COUNT(*) FROM TB_BOARD WHERE DEL_GB = 'N' ) AS TOTAL_COUNT , IDX, TITLE, HIT_CNT, CREA_DTM FROM TB_BOARD WHERE DEL_GB= 'N' ORDER BY IDX DESC LIMIT #{START} , #{END} ]]> </select>
- LIMIT에 #{START}는 몇번 째부터 시작할 지를 나타내고, #{END}는 몇 개의 칼럼을 가져올 지 정한다. TOTAL_COUNT는 게시물 총 갯수를 구하기 위함이다.
- 게시물 추가하기(프로시저 생성)
DELIMITER $$ CREATE PROCEDURE myFunction() BEGIN DECLARE i INT DEFAULT 1; WHILE (i < 501) DO INSERT INTO TB_BOARD(TITLE, CONTENTS, HIT_CNT, DEL_GB, CREA_DTM, CREA_ID) VALUES(concat('제목',i), concat('내용',i), 0, 'N', SYSDATE(), 'Admin'); SET i = i + 1; END WHILE; END$$ DELIMITER ;
- 프로시저 실행
CALL myFunction;
페이징 테스트를 위하여 많은 양의 게시물을 생성해 넣는다.
2. 코드 작성
2.1 AbstractDAO.java
해당 코드를 AbstractDAO.java 에 추가 작성하라.
@SuppressWarnings({ "rawtypes", "unchecked" }) public Map selectPagingList(String queryId, Object params){ printQueryId(queryId); Map<String,Object> map = (Map<String,Object>)params; PaginationInfo paginationInfo = null; if(map.containsKey("currentPageNo") == false || StringUtils.isEmpty(map.get("currentPageNo")) == true) map.put("currentPageNo","1"); paginationInfo = new PaginationInfo(); paginationInfo.setCurrentPageNo(Integer.parseInt(map.get("currentPageNo").toString())); if(map.containsKey("PAGE_ROW") == false || StringUtils.isEmpty(map.get("PAGE_ROW")) == true){ paginationInfo.setRecordCountPerPage(15); } else{ paginationInfo.setRecordCountPerPage(Integer.parseInt(map.get("PAGE_ROW").toString())); } paginationInfo.setPageSize(10); int start = paginationInfo.getFirstRecordIndex(); int end = paginationInfo.getRecordCountPerPage(); map.put("START",start); map.put("END",end); params = map; Map<String,Object> returnMap = new HashMap<String,Object>(); List<Map<String,Object>> list = sqlSession.selectList(queryId,params); if(list.size() == 0){ map = new HashMap<String,Object>(); map.put("TOTAL_COUNT",0); list.add(map); if(paginationInfo != null){ paginationInfo.setTotalRecordCount(0); returnMap.put("paginationInfo", paginationInfo); } } else{ if(paginationInfo != null){ paginationInfo.setTotalRecordCount(Integer.parseInt(list.get(0).get("TOTAL_COUNT").toString())); returnMap.put("paginationInfo", paginationInfo); } } returnMap.put("result", list); return returnMap; }
- 6줄
페이지 설정 정보를 담는 클래스 선언.
- 8~12줄
현재 페이지에 대한 값을 가지고 있는 지 확인하고 없을 시에는 1페이지를 위하여 1의 값을 설정 후 페이지 설정 변수에 세팅.
- 13~19줄
게시물 숫자가 설정되어 있지 않으면 15로 설정하고 페이지의 갯수 10으로 설정
- 21~24줄
페이지 설정 클래스의 첫번째 값의 인덱스 값과 게시물 숫자를 가져와 map에 값을 추가하여 준다.(SQL에서 사용)
- 29줄
쿼리의 결과 값을 가져온다.
- 31~47줄
쿼리의 결과값을 통해 TOTAL_COUNT 값을 가져오고 페이지 설정 클래스를 map에 추가한다.
- 48~49줄
페이시 설정 클래스와 쿼리 결과값을 포함한 map을 리턴한다.
2.2 JSP
- include-header.jspf
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %>
해당 태그를 추가한다.
- boardList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>게시물 리스트</title> <%@ include file="/WEB-INF/include/include-header.jspf" %> </head> <body> <table class="board_list"> <colgroup> <col width="5%"> <col width="50%"> <col width="5%"> <col width="15%"> <col width="15%"> </colgroup> <caption>게시판</caption> <thead> <tr> <th>No.</th> <th>제목</th> <th>Hit</th> <th>작성자</th> <th>작성시간</th> </tr> </thead> <tbody> <c:choose> <c:when test="${fn:length(list)>0}"> <c:forEach items="${list }" var="con" > <tr> <td>${con.IDX }</td> <td><input type="hidden" id="IDX" value="${con.IDX }"><a href="#this" name="TITLE">${con.TITLE }</a></td> <td>${con.HIT_CNT }</td> <td>${con.CREA_ID }</td> <td>${con.CREA_DTM }</td> </tr> </c:forEach> </c:when> <c:otherwise> <tr> <td>게시물이 존재하지 않습니다.</td> </tr> </c:otherwise> </c:choose> </tbody> </table> <c:if test="${not empty paginationInfo}"> <ui:pagination paginationInfo = "${paginationInfo}" type="text" jsFunction="fn_search"/> </c:if> <input type="hidden" id="currentPageNo" name="currentPageNo"/> <br><br> <a href="#this" class="btn" id="write">글쓰기</a> <%@ include file="/WEB-INF/include/include-body.jspf" %> <script type="text/javascript"> $(document).ready(function(){ $("#write").on("click",function(e){ e.preventDefault(); fn_openBoardWrite(); }) $("a[name='TITLE']").on("click",function(e){ e.preventDefault(); fn_openBoardDetail($(this)); }) }) function fn_openBoardWrite(){ var comSubmit = new ComSubmit(); comSubmit.setUrl("<c:url value='/sample/openBoardWrite.do'/>"); comSubmit.submit(); } function fn_openBoardDetail(val){ var comSubmit = new ComSubmit(); comSubmit.addParam("IDX",val.parent().find("#IDX").val()); comSubmit.setUrl("<c:url value='/sample/openBoardDetail.do'/>"); comSubmit.submit(); } function fn_search(pageNo){ var comSubmit = new ComSubmit(); comSubmit.setUrl("<c:url value='/sample/openBoardList.do' />"); comSubmit.addParam("currentPageNo", pageNo); comSubmit.submit(); } </script> </body> </html>
- 50~53줄
페이지 정보 클래스를 받아와서 페이징 태그 속성 값을 설정해주었다. jsFunction은 페이징 태그를 클릭하였을 때 실행시킬 함수를 지정한다.
- 83~88줄
페이징 태그 클릭 시 실행되는 함수를 설정해둔 것으로 pageNo라는 값은 페이징 태그를 클릭하는 값을 파라미터로 넘겨 줌으로써 currentPageNo 값으로 Controller로 파라미터를 추가하여 보낸다.
2.3 JAVA
게시물 리스트 관련 코드를 아래와 같이 수정하라.
- Controller
SampleController.java
@RequestMapping(value="/sample/openBoardList.do") public ModelAndView openBoardList(CommandMap commandMap) throws Exception{ ModelAndView mv = new ModelAndView("boardList"); Map<String,Object> map = sampleService.selectBoardList(commandMap.getMap()); mv.addObject("list", map.get("result")); mv.addObject("paginationInfo", (PaginationInfo)map.get("paginationInfo")); return mv; }
- List 값을 리턴하던 것을 Map으로 바꾸고 쿼리 결과 값과 페이징 정보 값을 맵에서 가져와 뷰로 보내준다. 여기서 페징 정보 값은 위의 boardList.jsp 에서 작성할 때 보았던 ui:paginationInfo 에서 보았던 ${paginationInfo}로 사용 될 것이다.
- Service, ServiceImpl
SampleServiceImpl.java
@Override public Map<String,Object> selectBoardList(Map<String, Object> map) throws Exception { return sampleDAO.selectBoardList(map); }
- DAO
SampleDAO.java
@SuppressWarnings("unchecked") public Map<String,Object> selectBoardList(Map<String,Object> map) throws Exception{ return (Map<String,Object>)selectPagingList("sample.selectBoardList",map); }
- Map 형식으로 바꾼 것을 주의하면서 코드를 수정한다. 여기는 또한 selectBoardList를 selectPagingList로 수정하는 것을 주의한다.
3. 테스트
- 게시물 리스트 페이지를 열어보자.
- 다음 2 페이지로 넘어가보자.
- 다음 버튼을 눌러 11페이지로 넘어가보자.
- 마지막 버튼을 클릭하여 동작하는지 보자.
- 위 작업들에 대한 로그이다.
- 위의 이미지들처럼 동작을 완료했다면 전자정부 프레임워크 라이브러리를 이용한 페이징도 완료하였다.
'코딩 > Spring' 카테고리의 다른 글
Spring 개발 - 게시판 만들기 번외(2) - 회원 기능(회원가입) (0) | 2018.03.13 |
---|---|
Spring 개발 - 게시판 만들기 번외(1) - 댓글 (2) | 2018.03.07 |
Spring 개발 - 게시판 만들기(16) - AOP 적용하기 (0) | 2018.03.02 |
Spring 개발 - 게시판 만들기(15) - 파일 다중 업로드 및 게시판 수정하기(파일 업로드) (0) | 2018.01.02 |
Spring 개발 - 게시판 만들기(14) - 파일 다운로드 (0) | 2018.01.01 |