#8_[spring boot] 게시판 목록 출력(페이징 처리, 부트스트랩) :: 개발/일상_Mr.lee

#8_[spring boot] 게시판 목록 출력(페이징 처리, 부트스트랩)

Posted by Mr.mandu.
2017. 12. 3. 06:30 개발/spring boot, gradle, mybatis Project

안녕하세요.

gradle, spring boot 를 활용하여

메인화면 까지 출력하였습니다.

그 이후에 쿼리를 로그로도 찍어보는 작업을 하였습니다.


[개발/spring boot, gradle, mybatis Project] - #6_[spring boot] 쿼리 로그 찍기(gradle, mybatis)

[개발/spring boot, gradle, mybatis Project] - #5_[spring boot] 부트스트랩(bootstrab) 시작하기(적용)

[개발/spring boot, gradle, mybatis Project] - #3_[spring boot] 프로젝트 처음 시작하기(jsp vieeResolver)



다른 것들은 제 카테고리에서 확인하세요.

이제 게시한 리스트를 출력해보겠습니다.


먼저 게 결과화면 입니다.


부트 스트랩을 이용하니 

디자인에 취약한 저도 그냥...초보수준의 디자인은 꾸릴수 있었습니다.


우선 검색 조건 및 페이징 처리할 VO를 하나 만들었습니다.



BoardSearchVO

package lee.board.service;

import lee.domain.ListPagingVO;
import lombok.Data;

@Data
public class BoardSearchVO extends ListPagingVO{
	
	private String title;
	private String usr_id;
	private String usr_name;
	private long bbs_sno;
	private long blt_rsrc_sno;

}

소스코드를 보시면 extends ListPagingVo를 확인 할 수 있습니다.

ListPagingVo는 페이징 처리에 공통 모듈로 사용할 목적으로 생성하였습니다.


ListPagingVo

package lee.domain;

import lombok.Data;

@Data
public class ListPagingVO {
	
	private int startRow;
	private int endRow;
	
	/** 현재페이지 */
    private int pageIndex = 1;
    
    /** 페이지사이즈 */
    private int pageSize = 10; //한페이지에 나오는 게시물 개수
    
    private int pageGroupSize = 3; // 페이지 번호 몇개 보여줄 것인지
}



저는현재 @Data 어노테이션을 활용하였기 때문에 Setter, Getter를 따로 생성하지 않았습니다.

Lombok 설치는 제 포스팅에 있지만 일단 실습을 하시는 분들은

Setter와 Getter를 생성해주세요.


그다음 Controller를 작성해보겠습니다.


BoardController

@RequestMapping(value = "/board/**/boardList")
    public String boardList(HttpServletRequest req, ModelMap modelMap, @ModelAttribute("boardSearchVO") BoardSearchVO boardSearchVO) {
		String jspPath =req.getRequestURI();
		   
		///////paging : S//////////////////////////////
		
		int pageSize = boardSearchVO.getPageSize();// 한페이지에 나오는 게시물 개수
		int pageIndex = boardSearchVO.getPageIndex(); //현재 선택한 페이지 number
		int pageGroupSize = boardSearchVO.getPageGroupSize(); // 페이지 번호가 몇개 나오느냐 개수
		int startRow = (pageIndex - 1) * pageSize + 1;// 한 페이지의 시작글 번호
		int endRow = pageIndex * pageSize;// 한 페이지의 마지막 글번호

		boardSearchVO.setStartRow(startRow);
		boardSearchVO.setEndRow(endRow);
		int count = boardService.boardCount(boardSearchVO); //게시물 총 개수

		int pageGroupCount = count / (pageSize * pageGroupSize) + (count % (pageSize * pageGroupSize) == 0 ? 0 : 1);
		int nowPageGroup = (int) Math.ceil((double) pageIndex / pageGroupSize);
		
		List<BoardVO> boardList = boardService.boardList(boardSearchVO);
		
		modelMap.put("pageIndex", pageIndex);
		modelMap.put("pageSize", pageSize);
		modelMap.put("count", count);
		modelMap.put("pageGroupSize", pageGroupSize);
		modelMap.put("nowPageGroup", nowPageGroup);
		modelMap.put("pageGroupCount", pageGroupCount);
		modelMap.put("articleList", boardList);
		modelMap.put("boardSearchVO", boardSearchVO);
		
        return jspPath;
    }


이따 작성될 jsp 와 연관되어 생각하다 보면 은근 복잡합니다.

저는 아직도 헷갈립니다.

각 변수 설명드리겠습니다.


변수설명

pagesize = 한페이지에 게시물이 몇개 나올것인가

pageIndex = 현재 몇번째 페이지인가

pageGroupSize = 페이지 그룹 출력 개수 

ex) [1],[2]  <<----이런 페이징 처리시 페이지 번호 개수


startRow = 시작글 번호(쿼리에서 활용)

endRow = 마지막 글 번호(쿼리에서 활용)


pageGroupCount= 페이징 처리 숫자가 몇개 출력될 것인지

ex) pageIndex =10, pageGroupSize=3, 총개시물수 : 23 일때

페이지번호는 [1][2][3] 이렇게 출력되야 함.

nowPageGroup = 현재 pageGroupCount 번재수

ex)nowPageGroup =1 이면 [1][2][3]

=2이면 [4][5][6]


포스팅 길이가 너무 길어져서

service, Impl, Mapper는 간단히 설명드리겠습니다.


service단 선언

int boardCount(BoardSearchVO boardSearchVO);

List<BoardVO> boardList(BoardSearchVO boardSearchVO);


Impl단 선언

public int boardCount(BoardSearchVO boardSearchVO) {

return boardMapper.boardCount(boardSearchVO);

}


public List<BoardVO> boardList(BoardSearchVO boardSearchVO){

return boardMapper.boardList(boardSearchVO);

}


Mapper단 선언

int boardCount(BoardSearchVO boardSearchVO);

List<BoardVO> boardList(BoardSearchVO boardSearchVO);


그리고 게시물의 개수와 게시 목록을 가져오는 쿼리 입니다.

이는 코드를 보시면 이해 될 거라 생각됩니다.


Count 쿼리

		 <select id="boardCount" parameterType="lee.board.service.BoardSearchVO" resultType="int"> 
		SELECT
			count(*)
		FROM
			table
	 </select>

총게시물 가져오는 쿼리

	<select id="boardList" parameterType="lee.board.service.BoardSearchVO" resultType="lee.domain.BoardVO">
		select
			컬럼명
		from(
			select
			 /*+ opt_param('_optimizer_cost_based_transformation', 'off') */
				blt_rsrc_sno, rownum as rnum
			from
			( 
				SELECT
					blt_rsrc_sno
				FROM
					table
				
			)
		)r1, table r2
		where
		r1.blt_rsrc_sno = r2.blt_rsrc_sno and 
		rnum between #{startRow} and #{endRow}
		order by r2.reg_date DESC
	 </select> 



테이블과 컬럼명은 본인것으로 작성해주세요.


이제 boardList.jsp파일 첨부하겠습니다.




boardList.jsp

	<div class="board_div">

          <h2 class="page-header">Notice</h2>
          
          <div class="search_div">
	          <form class="form" id="boardSearchVO" name="boardSearchVO">
	          <input type="hidden" id="pageIndex" name="pageIndex" value="${boardSearchVO.pageIndex}"/>
	          <input type="hidden" id="pageSize" name="pageSize" value="${boardSearchVO.pageSize}"/>
	          <input type="hidden" id="bbs_sno" name="bbs_sno" value="${boardSearchVO.bbs_sno}"/>
	          <input type="hidden" id="blt_rsrc_sno" name="blt_rsrc_sno" value="0"/>
	          
	         
	          <div class="row"> 
		          <div class="col-xs-2"> 
		          		<!-- <label for="usr_id">글쓴이(ID)</label> -->
					    <input type="text" class="form-control" id="usr_id" name="usr_id" value="${boardSearchVO.usr_id}" placeholder="input writer..."/>
		          </div> 
		          <div class="col-xs-4"> 
		          		<!-- <label for="title">제목</label> -->
					    <input type="text" class="form-control" id="title" name="title" value="${boardSearchVO.title}" placeholder="input title..."/>  
		          </div> 
				  <button type="submit" class="btn btn-default" id="searchBtn">Search</button> 
	          </div>
	          </form>
			</div>
        
          
          <h4>total : ${count}</h4>
          
          <div class="table-responsive">
            <table class="table table-striped"> <!-- table-hover -->
              <thead>
                <tr>
                  <th class="col-xs-1">번호</th>
                  <th class="col-xs-6">제목</th>
                  <th class="col-xs-2">글쓴이(ID)</th>
                  <th class="col-xs-1">조회수</th>
                  <th class="col-xs-2">등록일</th>
                </tr>
              </thead>
              <tbody>
               <c:choose>
					<c:when test="${not empty articleList}">
						<c:forEach items="${articleList}" var="vo" varStatus="idx">
	
							<tr class="${idx.count % 2 == 1 ? 'trOdd' : 'trEven'}">
								<td><c:choose>
										<c:when test="${count > pageSize}"> <!-- ex) count= 11, pageSize=10 -->
											<c:out
												value="${count - pageSize*(pageIndex-1) - idx.count +1}" /> <!-- 11,10,9,8.......... -->
										</c:when>
										<c:otherwise>
											<c:out value="${count  - idx.count +1}" />
										</c:otherwise>
	
									</c:choose>
								</td>

								<td>
								<a id="${vo.blt_rsrc_sno}" class="boardView" data-toggle="modal" href="#;" data-target="#modal-testNew" role="button" data-backdrop="static">	
								${vo.bbs_title}</a>
								</td>
								<td><c:out value="${vo.usr_id}"/></td>
								<td><c:out value="${vo.bbs_cnt}"/></td>
								<td><c:out value="${vo.reg_date}"/></td>
							</tr>
						</c:forEach>
					</c:when>
					<c:otherwise>
						<tr>
							<td colspan="7">조회된 자료가 없습니다.</td>
						</tr>
					</c:otherwise>
				</c:choose>
              </tbody>
            </table>
            </div>
           	<div class="pull-right"><a href="#" class="btn btn-primary btn-success boardAddBtn"><span class="glyphicon glyphicon-pencil"></span> Write</a></div>
            <!-- Paging : S -->
			<c:if test="${count > 0}">
				<c:set var="pageCount" value="${count / pageSize + ( count % pageSize == 0 ? 0 : 1)}" />
				<c:set var="startPage" value="${pageGroupSize*(nowPageGroup-1)+1}" />
				<c:set var="endPage" value="${startPage + pageGroupSize-1}" />
				
				<c:if test="${endPage > pageCount}">
					<c:set var="endPage" value="${pageCount}" />
				</c:if>

				<div class="jb-center" >
			
		            <ul class="pagination">
		            
		            	<c:if test="${nowPageGroup > 1}">
							<li><a href="#;" onclick='paging_script(${(nowPageGroup-2)*pageGroupSize+1 },${pageSize},"boardSearchVO","/board/notice/boardList");' ><span class="glyphicon glyphicon-chevron-left"></span></a></li>
						</c:if>
						
						<c:if test="${nowPageGroup == 1}">
							<!-- <li class="disabled"><a href="#"><span class="glyphicon glyphicon-chevron-left"></span></a></li> -->
						</c:if>
		
						<c:forEach var="i" begin="${startPage}" end="${endPage}">
							<li <c:if test="${pageIndex == i}"> class="active" </c:if>><a href="#;" onclick='paging_script(${i},${pageSize},"boardSearchVO","/board/notice/boardList");'>${i}</a></li>
						</c:forEach>
		              
		             	 <c:if test="${nowPageGroup < pageGroupCount}">
		             	 
							<li><a href="#;" onclick='paging_script(${nowPageGroup*pageGroupSize+1},${pageSize},"boardSearchVO","/board/notice/boardList");'><span class="glyphicon glyphicon-chevron-right"></span></a></li>
						</c:if>
		            </ul>
         	 </div>
          
			</c:if>
			<!-- Pageing : E -->
          </div>
        <!-- </div> --> 

가서 쫌 헷갈릴수도 있는부분이

아래 페이징 처리하는 곳일것이라 예상 됩니다.

하지만 조금만 고민해보시면 왜 그런지 아실것 같습니다.


아니면 댓글 남겨주시면 아는범위내에 답변드리겠습니다.

이제 게시판 목록을 출력하였으니

등록, 조회, 수정 순으로 진행 하면 될 것 같습니다.

감사합니다.