spring/게시판 만들기

[spring] 스프링게시판 페이징(paging) 처리

carrotdy 2022. 2. 18. 13:18

게시글이 여러개 있다면 한번에 모든 글이 보여지기 때문에 비효율적이다.
무한스크롤도 있고 더보기 기능도 있지만 페이징이 더 깔끔하고 효율적이라 이번에는 페이징처리로 작업을 해보았다.
다음에는 무한스크롤과 더보기 버튼 기능도 해봐야징ㅎㅎ 

 

 

페이징 원칙

- 페이징은 반드시 GET 방식으로 사용해야한다.

- 페이징은 필요한 번호만 출력해야하고, 원하는 번호를 선택하면 해당 페이지로 이동해서 목록을 보여주어야 한다.

- 이전과 다음 버튼이 존재해야 한다. 만약 총 게시물 수가 100개이고 한 페이지당 10개의 게시글을 볼 수 있다면
총 10개의 버튼이 필요하다. 만약 이전과 다음 버튼이 존재하지 않는다면 여러개의 버튼을 한번에 보여줘야하기 때문에 표시해줘야 한다. 

 

 

1. index.jsp

/board.do 뒤에 reqPage=1을 붙여준다. (/board.do 페이지는 자유게시판 페이지임)

   reqPage=1은 1페이지라는 의미

 

 

2. boardController

 

	//목록
	@RequestMapping(value="/board.do")
	public String board(int reqPage, Model model) {
		HashMap<String, Object> map = service.boardList(reqPage);

		model.addAttribute("pageNavi", map.get("pageNavi"));
		model.addAttribute("list", map.get("list"));
		model.addAttribute("start", map.get("start"));
		return "board/boardList";
	}

 

boardList.jsp

controller -> service -> dao ...을 통해 데이터를 가져와 map에 저장한다음 pageNavi, list, start를 boradList에 뿌려준다.
 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<c:import url="/WEB-INF/views/common/header.jsp"/>
	<div class="container">
		<fieldset>
			<legend>자유게시판</legend>
			<c:if test="${not empty sessionScope.m && (sessionScope.m.memberLevel eq 0 || sessionScope.m.memberLevel eq 1)}"> 
				<a class="btn btn-secondary" href='/boardWriteFrm.do' style="float:right; margin-bottom:5px;">글쓰기</a>
			</c:if>
			<table class="table table-hover">
			    <tr class="table-active">
			      <th scope="row">번호</th>
			      <th>제목</th>
			      <th>작성자</th>
			      <th>작성일</th>
			      <th>조회수</th>
			    </tr>
			    <c:forEach items="${list }" var="b" varStatus="i">
			    	<tr class="table-default">
			    		<td>${start + i.index }</td>
			    		<td><a href='/boardView.do?boardNo=${b.boardNo}' style="text-decoration:none;">${b.boardTitle}</a></td>
			    		<td>${b.boardWriter}</td>
			    		<td>${b.regDate}</td>
			    		<td>${b.readCount}</td>
			    	</tr>
			    </c:forEach>
			</table><br>
			<div id="pageNavi">${pageNavi }</div>
		</fieldset>
	</div>
	<c:import url="/WEB-INF/views/common/footer.jsp"/>
</body>
</html>

 

3. boardService

 

@Service
public class BoardService {
	@Autowired
	private BoardDao dao;

	public HashMap<String, Object> boardList(int reqPage) {
		int numPerPage = 10;  //한페이지당 게시물 수
		int end = reqPage * numPerPage;
		int start = end - numPerPage + 1;
		
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("start", start);
		map.put("end", end);
		
		ArrayList<Board> list = dao.boardList(map);
		
		int totalCount = dao.totalCount();  // 전체 게시물 수 조회
		int totalPage = 0;
		if(totalCount%numPerPage == 0) {
			totalPage = totalCount/numPerPage;
		}else {
			totalPage = totalCount/numPerPage + 1;
		}

		int pageNaviSize=5;  // 페이지 네비 길이(1~5, 6~10...)
		int pageNo = 1;
		if(reqPage>4) {
			pageNo= reqPage-2;
			if(totalPage - reqPage < (pageNaviSize-1)) {
				pageNo = totalPage-(pageNaviSize-1);
			}
		}
		
		String pageNavi = "<ul class='pagination pagination-lg'>";
		if(pageNo != 1) {  // 이전버튼
			pageNavi += "<li class='page-item disabled'><a class='page-link' href='/board.do?reqPage="+(reqPage-1)+"'>&lt;</a></li>";
		}
		for(int i=0;i<pageNaviSize;i++) {  // 페이지숫자
			if(pageNo == reqPage) {
				pageNavi += "<li class='page-item active'><a class='page-link' href='/board.do?reqPage="+pageNo+"'>"+pageNo+"</a></li>";
			}else {
				pageNavi += "<li class='page-item'><a class='page-link' href='/board.do?reqPage="+pageNo+"'>"+pageNo+"</a></li>";
			}
			pageNo++;
			if(pageNo > totalPage) {  // 최종 페이지보다 네이비게이션 시작번호가 더 클경우 break
				break;
			}
		}
		if(pageNo <= totalPage) {  // 다음버튼
			pageNavi += "<li class='page-item'><a class='page-link' href='/board.do?reqPage="+(reqPage+1)+"'>&gt;</a><li>";
		}
		pageNavi += "</ul>";
		
		map.put("pageNavi", pageNavi);
		map.put("list",	list);
		
		return map;
	}

 

4. boardDao

 

@Repository
public class BoardDao {
	@Autowired
	private SqlSessionTemplate session;

	public ArrayList<Board> boardList(HashMap<String, Object> map) {
		List<Board> list = session.selectList("board.boardList", map);
		return (ArrayList<Board>)list;
	}

 

5. boardSQL.xml

 

	// 페이징처리 게시글 조회
	<select id="boardList" parameterType="map" resultType="b">
		select 
			board_no as boardNo,
			board_title as boardTitle,
			board_content as boardContent,
			board_writer as boardWriter,
			readCount,
			regDate,
			priority,
			fileName,
			filePath,
			ncCount
		from (select rownum as rnum, b.* from (SELECT * FROM board order by 1 desc)b) board 
		where rnum between #{start} and #{end}
	</select>
	
	// 게시물 총 갯수
	<select id="totalCount" parameterType="int" resultType="int">
		select count(*) from board
	</select>

 

 

페이징 디자인은 bootswatch를 이용하였다.

디자인을 변경하고 싶다면 bootswatch에서 원하는 디자인 다운받은 후에 boardService pageNavi 부분을 변경해주면 된다! 

 

반응형