게시물 목록 화면과 페이징 - TDD
1. 게시물 목록 페이징
2. LIMIT offset, row_count
ex) LIMIT 10, 10 이면
10개 건너뛰고 그 다음부터 10개를 읽어온다.
package com.fastcampus.ch4.domain;
public class PageHandler {
private int totalCnt; // 총 게시물 갯수
private int pageSize; // 한 페이지의 크기
private int naviSize = 10; // 페이지 내비게이션의 크기
private int totalPage; // 전체 패이지의 갯수
private int page; // 현재 페이지
private int beginPage; // 내비게이션의 첫 번째 페이지
private int endPage; // 내비게이션의 마지막 페이지
private boolean showPrev; // 이전 페이지로 이동하는 링크를 보여줄 것인지의 여부
private boolean showNext; // 다음 페이지로 이동하는 링크를 보여줄 것인지의 여부
public PageHandler (int totalCnt, int page) {
this(totalCnt, page, 10);
}
public PageHandler (int totalCnt, int page, int pageSize) {
this.totalCnt = totalCnt;
this.page = page;
this.pageSize = pageSize;
totalPage = (int)Math.ceil(totalCnt / (double)pageSize);
beginPage = (page-1) / naviSize * naviSize + 1;
endPage = Math.min(beginPage + naviSize - 1, totalPage);
showPrev = beginPage != 1;
showNext = endPage != totalPage;
}
void print() {
System.out.println("page = " + page);
System.out.print(showPrev ? "[PREV] " : "");
for (int i = beginPage; i <= endPage; i++) {
System.out.print(i+" ");
}
System.out.println(showNext ? "[NEXT]" : "");
}
}
package com.fastcampus.ch4.domain;
import org.junit.Test;
import static org.junit.Assert.*;
public class PageHandlerTest {
@Test
public void test() {
PageHandler ph = new PageHandler(250, 1);
ph.print();
System.out.println("ph = " + ph);
assertTrue(ph.getBeginPage() ==1);
assertTrue(ph.getEndPage() ==10);
}
@Test
public void test2() {
PageHandler ph = new PageHandler(250, 11);
ph.print();
System.out.println("ph = " + ph);
assertTrue(ph.getBeginPage() ==11);
assertTrue(ph.getEndPage() ==20);
}
@Test
public void test3() {
PageHandler ph = new PageHandler(255, 25);
ph.print();
System.out.println("ph = " + ph);
assertTrue(ph.getBeginPage() ==21);
assertTrue(ph.getEndPage() ==26);
}
}
페이지를 관리하는 클래스인 PageHandler를 만들고 테스트 메소드로 테스트를 했다.
이제 Service와 PageHandler를 이용하여 BoardController를 만들 수 있다.
package com.fastcampus.ch4.controller;
import com.fastcampus.ch4.domain.BoardDto;
import com.fastcampus.ch4.domain.PageHandler;
import com.fastcampus.ch4.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@GetMapping("/list")
public String list(Integer page, Integer pageSize, Model m, HttpServletRequest request) {
if(!loginCheck(request))
return "redirect:/login/login?toURL="+request.getRequestURL(); // 로그인을 안했으면 로그인 화면으로 이동
if(page==null) page=1;
if(pageSize==null) pageSize=10;
try {
int totalCnt = boardService.getCount();
PageHandler pageHandler = new PageHandler(totalCnt, page, pageSize);
Map map = new HashMap();
map.put("offset", (page-1)*10);
map.put("pageSize", pageSize);
List<BoardDto> list = boardService.getPage(map);
m.addAttribute("list", list);
m.addAttribute("ph", pageHandler);
} catch (Exception e) {
e.printStackTrace();
}
return "boardList"; // 로그인을 한 상태이면, 게시판 화면으로 이동
}
private boolean loginCheck(HttpServletRequest request) {
// 1. 세션을 얻어서
HttpSession session = request.getSession();
// 2. 세션에 id가 있는지 확인, 있으면 true를 반환
return session.getAttribute("id")!=null;
}
}
쿼리 스트링으로 page와 pageSize를 입력할 수 있는데, 입력이 없는 경우 1페이지를 보여주고 10개의 글을 보여주도록 설정하였다.
boardService의 getCount 메소드를 이용해 총 글의 개수(totalCnt)를 얻는다.
totalCnt와 page, pageSize를 생성자 매개변수로 하여 pageHandler를 얻는다.
map에는 건너뛸 글의 갯수인 (page-1)*10 와 보여줄 글의 갯수 pageSize를 저장한 후
boardService의 getPage 메소드를 이용하여 해당 페이지에서 보여줄 글들을 list에 저장하였다.
그리고 list와 pageHandler를 Model에 저장하여 View인 boardList.jsp에 전달한다.
boardList.jsp 파일은 다음과 같이 작성하였다.
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fastcampus</title>
<link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='/login/login'/>">login</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div><div style="text-align:center">
<table border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>이름</th>
<th>등록일</th>
<th>조회수</th>
</tr>
<c:forEach var="board" items="${list}">
<tr>
<td>${board.bno}</td>
<td>${board.title}</td>
<td>${board.writer}</td>
<td>${board.reg_date}</td>
<td>${board.view_cnt}</td>
</tr>
</c:forEach>
</table>
<br>
<div>
<c:if test="${ph.showPrev}">
<a href="<c:url value='/board/list?page=${ph.beginPage-1}&pageSize=${ph.pageSize}'/>"><</a>
</c:if>
<c:forEach var="i" begin="${ph.beginPage}" end="${ph.endPage}">
<a href="<c:url value='/board/list?page=${i}&pageSize=${ph.pageSize}'/>">${i}</a>
</c:forEach>
<c:if test="${ph.showNext}">
<a href="<c:url value='/board/list?page=${ph.endPage+1}&pageSize=${ph.pageSize}'/>">></a>
</c:if>
</div>
</div>
</body>
</html>
먼저 table(표)를 만들고, 표의 내용을 Model에 저장한 list에서 글을 하나씩 꺼내서 해당 글의 번호, 제목, 이름, 등록일, 조회수로 채운다.
그리고 pageHandler에 저장된 값을 이용해서 표 아래의 페이지 이동 부분을 작성한다.
페이지가 10이 넘어가서 이전의 10개 이상의 페이지가 존재하게 되면 < (<) 버튼이 생긴다.
쿼리 스트링에 넣어준 page와 pageSize에 따라, 이동할 수 있는 페이지 숫자가 10개씩 출력되고 각 링크를 클릭하면
해당 페이지로 이동할 수 있게 링크를 만들었다.
다음 10개의 페이지로 넘어갈 수 있으면 > (>) 버튼이 생긴다
출처 : 스프링의 정석 : 남궁성과 끝까지 간다
'Spring & SpringBoot > Spring' 카테고리의 다른 글
220512 Spring - Chapter 4. MyBatis로 게시판 만들기(Part.4) (0) | 2022.05.13 |
---|---|
220511 Spring - Chapter 4. MyBatis로 게시판 만들기(Part.3) (0) | 2022.05.12 |
220509 Spring - Chapter 4. MyBatis로 게시판 만들기 (0) | 2022.05.10 |
220506 Spring - Chapter 3. Spring DI와 AOP (Part. 6) (0) | 2022.05.07 |
220505 Spring - Chapter 3. Spring DI와 AOP (Part. 5) (0) | 2022.05.06 |