Back-End/Spring

[Spring] 예제 2 - 페이징 처리

09009 2023. 5. 22. 12:44

테스트 코드 작성

아래 작성된 코드를 100번 이상 실행시킨다.

페이징 처리의 필요성

현재 게시글 데이터가 160여개가 추가되었는데 이 많은 양의 데이터를 한 페이지에 담기에는 사용자 입장에서 이용이 불편할 것이다.

→ 한 페이지에 있는 데이터의 양이 너무 많다.

 

mainPage.jsp

ul 태그에 mb-0 작성 (글쓰기 버튼 크기 커지지 않게 하기 위해)

mx-auto : 양 옆의 margin을 가운데로

< 이전 특수문자

> 이후 특수문자

		<div class="row"><!-- 버튼 -->
			<div class="col-6">
				<nav aria-label="Page navigation example">
				  <ul class="pagination">
				    <li class="page-item"><a class="page-link" href="#">Previous</a></li>
				    <li class="page-item"><a class="page-link" href="#">1</a></li>
				    <li class="page-item"><a class="page-link" href="#">2</a></li>
				    <li class="page-item"><a class="page-link" href="#">3</a></li>
				    <li class="page-item"><a class="page-link" href="#">4</a></li>
				    <li class="page-item"><a class="page-link" href="#">5</a></li>
				    <li class="page-item"><a class="page-link" href="#">Next</a></li>
				  </ul>
				</nav>
			</div>

		
			<div class="col-2 ms-auto d-grid">
				<c:if test="${!empty sessionUser }">
					<a href="./writeContentPage" class="btn btn-primary">글쓰기</a>
				</c:if>
			</div>
		</div>
	
	</div>

 

ROWNUM: 출력하는 순서대로 일련번호를 붙여주는 것

ORDER BY가 먼저 적용되는 것이 아니라 출력이 먼저된다.

ORDER BY가 나중에 수행된다.

 

→ ORDER BY를 먼저 수행하고 ROWNUM을 붙여야 한다. 순서를 바꿀 때 서브쿼리 사용

ROWNUM: 출력하고 나서 수행된다

동작순서 주의할 것

잘못된 코드

 

((1-1)*10)+1

첫 1: 페이지번호

10개씩 보기 페이징 쿼리

 

 

ORDER BY를 먼저 한 다음에 ROWNUM을 붙여야함.

mainPage.jsp

	<div class="col-6 mx-auto">
				<nav aria-label="Page navigation example">
				  <ul class="pagination mb-0">
				    <li class="page-item"><a class="page-link" href="#">&lt;</a></li>
				    <li class="page-item"><a class="page-link" href="./mainPage?page=1">1</a></li>
				    <li class="page-item"><a class="page-link" href="./mainPage?page=2">2</a></li>
				    <li class="page-item"><a class="page-link" href="./mainPage?page=3">3</a></li>
				    <li class="page-item"><a class="page-link" href="./mainPage?page=4">4</a></li>
				    <li class="page-item"><a class="page-link" href="./mainPage?page=5">5</a></li>
				    <li class="page-item"><a class="page-link" href="#">&gt;</a></li>
				  </ul>
				</nav>
			</div>

쿼리

SELECT COUNT(*) FROM fp_board;

BoardSqlMapper 

selectAll 메서드 수정

	public List<BoardDto> selectAll(int pageNum);
	// 글 개수 가져오는 것
	public int getBoardCount();

<= 는 xml에서 특수문자로 인식

<![CDATA[]]>

크고 작음을 비교하는 쿼리를 작성할때 사용

<select id="selectAll" resultType="com.ja.finalproject.dto.BoardDto">
	
		<![CDATA[
		SELECT t2.* FROM (
		      SELECT t1.*, ROWNUM rnum FROM(
		          SELECT fb.* FROM fp_board fb
		          ORDER BY id DESC
		    ) t1
		) t2
		
		WHERE t2.rnum >= ((#{pageNum}-1)*10)+1 AND t2.rnum <= #{pageNum}*10
		]]>
		
	</select>
	
	<select id="getBoardCount" resultType="int">
		SELECT COUNT(*) FROM fp_board
	</select>

BoardServiceImpl

메서드 수정

		public List<Map<String, Object>> getBoardList(int pageNum) {
			
			// List는 object를 주로 담진 않는다. 일률적으로 담는다.
			List<Map<String, Object>> list = new ArrayList<>();
			
			List<BoardDto> boardDtoList =  boardSqlMapper.selectAll(pageNum);
			
			for(BoardDto boardDto : boardDtoList) {
				// 한 바퀴 돌때마다 map이 생성되어야 한다.	map은 키가 중복되면 안된다.
				Map<String, Object> map = new HashMap<>();
				
				int memberId = boardDto.getMember_id();
				System.out.println(memberId);
				
				MemberDto memberDto = memberSqlMapper.selectById(memberId); 
				System.out.println(memberDto);
				
				map.put("memberDto", memberDto);
				map.put("boardDto", boardDto);
				
				list.add(map);

			}
			return list;
		}

BoardController

	@RequestMapping("mainPage")
	public String mainPage(Model model, int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		
		return "board/mainPage";
	}

서버 가동

(중요)

@RequestParam

@RequestParam(value = "aaa") int page

외부에서 aaa라고 보내면 서버에서 page로 인식

 

defaultValue

만약에 파라미터가 날라오지 않으면 null로 인식할텐데 파라미터가 날라오지 않은 경우 page라는 변수에 1을 설정하겠다는 뜻

@RequestMapping("mainPage")
	public String mainPage(Model model, @RequestParam(value = "page", defaultValue = "1" ) int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		
		return "board/mainPage";
	}

 

BoardServiceImpl

		public int getBoardCount() {
			return boardSqlMapper.getBoardCount();
		}

BoardController

	@RequestMapping("mainPage")
	public String mainPage(Model model, @RequestParam(value = "page", defaultValue = "1") int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);
		
		int boardCount = boardService.getBoardCount();
		int totalPage = (int)Math.ceil(boardCount / 10.0);

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		model.addAttribute("totalPage", totalPage);
		
		return "board/mainPage";
	}

mainPage.jsp

		<div class="col-6 mx-auto">
				<nav aria-label="Page navigation example">
				  <ul class="pagination mb-0">
				    <li class="page-item"><a class="page-link" href="#">&lt;</a></li>
				    
				    <c:forEach begin="1" end="${totalPage}" var="index">
				    	<li class="page-item"><a class="page-link" href="./mainPage?page=${index}">${index}</a></li>			    
				    </c:forEach>
				    
				    <li class="page-item"><a class="page-link" href="#">&gt;</a></li>
				  </ul>
				</nav>
			</div>

BoardController

	@RequestMapping("mainPage")
	public String mainPage(Model model, @RequestParam(value = "page", defaultValue = "1") int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);
		
		int boardCount = boardService.getBoardCount();
		int totalPage = (int)Math.ceil(boardCount / 10.0);

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		model.addAttribute("totalPage", totalPage);
		model.addAttribute("currentPageNum", page);
		
		return "board/mainPage";
	}

mainPage.jsp

<div class="col-6 mx-auto">
				<nav aria-label="Page navigation example">
				  <ul class="pagination mb-0">
				    <li class="page-item"><a class="page-link" href="#">&lt;</a></li>
				    
				    <c:forEach begin="1" end="${totalPage}" var="index">
				    
				    	<c:choose>
				    		<c:when test="${index == currentPage}">
				    			<li class="page-item active"><a class="page-link" href="./mainPage?page=${index}">${index}</a></li>			
				    		</c:when>
				    		<c:otherwise>
				    			<li class="page-item"><a class="page-link" href="./mainPage?page=${index}">${index}</a></li>			
				    		</c:otherwise>
				    	</c:choose>
				    	
				    	    
				    </c:forEach>
				    
				    <li class="page-item"><a class="page-link" href="#">&gt;</a></li>
				  </ul>
				</nav>
			</div>

BoardController

	@RequestMapping("mainPage")
	public String mainPage(Model model, @RequestParam(value = "page", defaultValue = "1") int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);
		
		int boardCount = boardService.getBoardCount();
		int totalPage = (int)Math.ceil(boardCount / 10.0);
		
		// 1 2 3 4 5     6 7 8 9 10
		int startPage = ((page - 1) / 5) * 5 + 1;
		int endPage = ((page - 1) / 5+1) * 5;

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		model.addAttribute("totalPage", totalPage);
		model.addAttribute("currentPage", page);
		
		return "board/mainPage";
	}

보통 페이지 처리할때는 object를 만드는 편이다.

	@RequestMapping("mainPage")
	public String mainPage(Model model, @RequestParam(value = "page", defaultValue = "1") int page) {
		
		List<Map<String, Object>> list =  boardService.getBoardList(page);
		
		int boardCount = boardService.getBoardCount();
		int totalPage = (int)Math.ceil(boardCount / 10.0);
		
		// 1 2 3 4 5     6 7 8 9 10
		int startPage = ((page - 1) / 5) * 5 + 1;
		int endPage = ((page - 1) / 5+1) * 5;
		
		// endPage가 totalPage
		if (endPage > totalPage) {
			endPage = totalPage;
		}

		model.addAttribute("list", list); //request 객체에 담는다고 생각.
		model.addAttribute("totalPage", totalPage);
		model.addAttribute("currentPage", page);
		
		model.addAttribute("startPage", startPage);
		model.addAttribute("endPage", endPage);
		
		return "board/mainPage";
	}

 

		<div class="col-6 mx-auto">
				<nav aria-label="Page navigation example">
				  <ul class="pagination mb-0">
				    <li class="page-item"><a class="page-link" href="./mainPage?page=${startPage -1}">&lt;</a></li>
				    
				    <c:forEach begin="${startPage}" end="${endPage}" var="index">
				    
				    	<c:choose>
				    		<c:when test="${index == currentPage}">
				    			<li class="page-item active"><a class="page-link" href="./mainPage?page=${index}">${index}</a></li>			
				    		</c:when>
				    		<c:otherwise>
				    			<li class="page-item"><a class="page-link" href="./mainPage?page=${index}">${index}</a></li>			
				    		</c:otherwise>
				    	</c:choose>
				    	
				    	    
				    </c:forEach>
				    
				    <li class="page-item"><a class="page-link" href="${endPage + 1}">&gt;</a></li>
				  </ul>
				</nav>
			</div>
 <div class="row"><!-- 버튼 -->
         <div class="col-6 mx-auto">
            <nav aria-label="Page navigation example">
               <ul class="pagination mb-0">
                  <c:choose>
                     <c:when test="${startPage <= 1}">
                        <li class="page-item disabled"><a class="page-link" href="./mainPage?page=${startPage-1}">&lt;</a></li>
                     </c:when>
                     <c:otherwise>
                        <li class="page-item"><a class="page-link" href="./mainPage?page=${startPage-1}">&lt;</a></li>
                     </c:otherwise>
                  </c:choose>
                  <!-- 페이지 번호 -->
                  <c:forEach begin="${startPage }" end="${endPage }" var="index">
                     <c:choose>
                        <c:when test="${index == currentPage}">
                           <li class="page-item active"><a class="page-link" href="./mainPage?page=${index }">${index }</a></li>
                        </c:when>
                        <c:otherwise>
                           <li class="page-item"><a class="page-link" href="./mainPage?page=${index }">${index }</a></li>
                        </c:otherwise>
                     </c:choose>
                  </c:forEach>
                  <c:choose>
                     <c:when test="${endPage >= totalPage}">
                         <li class="page-item disabled"><a class="page-link" href="./mainPage?page=${endPage+1}">&gt;</a></li>
                     </c:when>
                     <c:otherwise>
                         <li class="page-item"><a class="page-link" href="./mainPage?page=${endPage+1}">&gt;</a></li>
                     </c:otherwise>
                  </c:choose>
               </ul>
            </nav>   
         </div>
댓글수0