관리자 글쓰기

본 내용은 혼자 공부하기 위하여 다른 포스트를 보면서 저에게 필요한 부분과 궁금했던 부분을 추가하여 게시하는 곳입니다.

궁금한 것에 대한 것은 모르는 것이 많겠지만 함께 알아보도록 노력하겠습니다.


참조 게시 포스트 : 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);
	}
- 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페이지로 넘어가보자.


- 마지막 버튼을 클릭하여 동작하는지 보자.


- 위 작업들에 대한 로그이다.


- 위의 이미지들처럼 동작을 완료했다면 전자정부 프레임워크 라이브러리를 이용한 페이징도 완료하였다.