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)+"'><</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)+"'>></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 부분을 변경해주면 된다!
반응형