-
2일차 - 게시물 목록의 페이징 처리프로젝트 일지/Spring 프로젝트- 헬스 커뮤니티 2023. 2. 21. 16:59
Spring 개발 - 게시판 만들기 #페이징 처리 (1)
이전에 만든 CRUD 게시판은 100개의 게시글이 있다면 한번에 100개의 게시글이 모두 보여진다. 정말 비효율적인 게시판이다..(ㅎ) 그래서 게시판 목록 페이징 처리를 하려고 한다. 그러면 좀 더 게
to-dy.tistory.com
게시물 상세조회 (detail.jsp 등)은 다른 팀원분이 작업 중이시다.
아직 댓글까지는 뜨지 않는데, 게시물 내용물들은 화면에 잘 떠서 지금까지의 내 작업물과 합쳤다.
페이징은 한 페이지에 게시물 10개씩, 페이지 번호는 5개씩 보이게 하였다.
또한 상세조회 페이지에서 "목록으로 돌아가기"를 클릭하면
무조건 1페이지가 아닌, 해당 게시물이 있던 페이지로 돌아가게 하였다.
찾아보니 대부분 Mybatis를 통해 작업하던데, 이번 프로젝트에서는 Mybatis를 쓰지 않으므로
구글링한 블로그를 참고하여 나의 케이스에 맞게 작성하였다.
postList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>게시물 목록</title> <style> td{ text-align: center; } </style> </head> <body> <h1>헬스 커뮤니티</h1> <br><br> <a href="">로그아웃</a> <a href="./mypage">마이페이지</a> <br><br> <c:if test="${fn:length(postList) == 0}"> <table width=500> <tr> <th>NO.</th> <th>제목</th> <th>글쓴이</th> <th>조회수</th> <th>등록일</th> </tr> <tr> <td colspan="5">게시물이 없습니다.</td> </tr> </table> </c:if> <form action="./regist" method="get"> <c:if test="${fn:length(postList) > 0}"> <table width=500> <tr> <th>NO.</th> <th>제목</th> <th>글쓴이</th> <th>조회수</th> <th>등록일</th> </tr> <c:forEach var="post" items="${postList}"> <tr> <td>${post.idx}</td> <td><a href="./search?postId=${post.postId}">${post.postTitle}</a></td> <td>${post.memberId}</td> <td>${post.readCount}</td> <td><fmt:formatDate value="${post.postDate}" pattern="yyyy-MM-dd"/></td> </tr> </c:forEach> </table> </c:if> <br> <input type="submit" value="새 게시물 등록"> </form> <br> <!-- paging --> - <c:if test="${paging.prev}"> <a href='<c:url value="./list?page=${paging.startPage-1}"/>'>이전</a> </c:if> <c:forEach begin="${paging.startPage}" end="${paging.endPage}" var="pageNum"> <a href='<c:url value="/list?page=${pageNum}"/>'>${pageNum}</a> </c:forEach> <c:if test="${paging.next}"> <a href='<c:url value="/list?page=${paging.endPage+1}"/>'>다음</a> </c:if> - </body> </html>
detail.jsp → 팀원분이 아직 작업 중. 나는 이전에 있던 페이지로 되돌아가는 a태그만 붙였다.
<%@page import="bit.com.app.vo.CommentVO"%> <%@page import="java.util.ArrayList"%> <%@page import="bit.com.app.utils.DateService"%> <%@page import="java.net.URLEncoder"%> <%@page import="bit.com.app.vo.PostVO"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h1>상세페이지</h1> <br> <a href='<c:url value='./list?page=${page}'/>'>목록으로</a> <br><br> <% PostVO post = (PostVO)request.getAttribute("post"); ArrayList<CommentVO> clist = (ArrayList<CommentVO>) request.getAttribute("clist"); %> <form action="./list" method="post"> <input type="hidden" name="seq" value=""> <table> <tr><td>제목</td><td><input type="text" name="title" value="${post.postTitle}" readonly="readonly"></td><td></td></tr> <!-- text --> <tr><td>내용</td> <td><textarea cols="80" rows="5" name="content" id="content" readonly="readonly">${post.postContent}</textarea></td> <td></td></tr> <!-- textarea --> <tr><td>작성자</td><td><input type="text" name="writer" value="${post.memberId}" readonly="readonly"></td><td></td></tr><!-- text --> <tr><td>조회수</td><td><input type="text" name="readCount" value="${post.readCount}" readonly="readonly"></td><td></td></tr><!-- text --> <tr><td>작성일자</td> <td><input type="text" name="createDate" value="${post.postDate}" readonly="readonly"></td> <%-- <c:if test="${fn:length(clist)>0}"> <table> <tr><th>글번호</th><th>닉네임</th><th>글제목</th><th>조회수</th> <c:forEach var="comment" items="${clist}"> </c:forEach> </table> </c:if> <c:if test="${fn:length(clist)==0}"> 게시 정보가 없습니다. </c:if> --%> </tr> <td><input type="submit" value="확인"></td> <td><input type="submit" value="수정"></td><td></td> </tr><!-- submit --> </table> </form> <div> <form action="./commentwrite" method="post" > <p> <label>댓글 작성자</label> <input type="text" name="memberId"> </p> <p> <textarea rows="5" cols="50" name="commentContent"></textarea> </p> <p> <input type="hidden" name="postId" value="${post.postId}"> <input type="hidden" name="commentDate" value="<%=DateService.getDateInfo(2)%>"> <button type="submit">댓글 작성</button> </p> </form> </div> </body> </html>
PostController.java
@Controller public class PostController { @Autowired private PostService postService; private int currentPage; /* basic (로그인 창으로 이동) */ /* 게시물 목록 (기본) */ @RequestMapping(value = "/main", method = RequestMethod.GET) public ModelAndView postList() { ModelAndView mav = new ModelAndView(); String url = "redirect:./list?page=1"; mav.setViewName(url); return mav; } /* 게시물 목록 (+페이징) */ @RequestMapping(value = "/list", method = RequestMethod.GET) public ModelAndView postList2(Criteria cri, @RequestParam("page") int currentPage) { ModelAndView mav = new ModelAndView(); String url = "./post/postList"; this.currentPage = currentPage; Paging paging = new Paging(); paging.setCri(cri); // 페이지 당 게시물 개수 cri.setCurrentPage(currentPage); // 현재 페이지 번호 paging.setTotalCount(postService.countList()); // 총 게시물 개수 List<PostVO> postList = postService.searchAll(cri); mav.addObject("postList", postList); mav.addObject("paging", paging); mav.setViewName(url); return mav; } /* 게시글 상세조회 */ @RequestMapping(value = "/search", method = RequestMethod.GET) public ModelAndView detail(@RequestParam("postId") int postId) { ModelAndView mav = new ModelAndView(); PostVO post = postService.detail(postId); // ArrayList<CommentVO> clist= commentservice.clist(); 이거는 댓글보기인데 일단 미구현 // mav.addObject("clist", clist); // 페이징 mav.addObject("page", this.currentPage); mav.addObject("post", post); String url = "./post/detail"; mav.setViewName(url); return mav; } }
PostService.java
@Service public class PostService { @Autowired private PostDAO postDAO; /* 게시물 목록 */ public List<PostVO> searchAll(Criteria cri) { List<PostVO> postList = null; try { postList = postDAO.selectAll(cri); } catch (SQLException e) { e.printStackTrace(); } return postList; } /* 게시판 전체 게시글 수 */ public int countList() { int count = 0; try { count = postDAO.countAll(); } catch (SQLException e) { e.printStackTrace(); } return count; } /* 게시글 상세조회 */ public PostVO detail(int postId) { PostVO post = null; try { post= postDAO.search(postId); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return post; } }
PostDAO.java
@Repository public class PostDAO { @Autowired private DataSource dataSource; private Connection con; private Statement stmt; private PreparedStatement pstmt; private ResultSet rs; private String sql; /* 게시물 목록 */ public List<PostVO> selectAll(Criteria cri) throws SQLException { sql = "select *, row_number() over(order by post_id) as idx from post order by idx desc limit ?,?"; con = dataSource.getConnection(); pstmt = con.prepareStatement(sql); pstmt.setInt(1, cri.getPageStart()); pstmt.setInt(2, cri.getPerPageNum()); rs = pstmt.executeQuery(); List<PostVO> postList = new ArrayList<PostVO>(); while(rs.next()) { PostVO post = new PostVO(rs.getInt(9), rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getInt(5), rs.getString(6), rs.getString(7), rs.getTimestamp(8)); postList.add(post); } ConnectionManager.closeConnection(rs, pstmt, con); return postList; } /* 게시판 전체 게시글 수 */ public int countAll() throws SQLException { sql = "select count(*) from post"; con = dataSource.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery(sql); rs.next(); int count = rs.getInt(1); return count; } /* 게시글 상세조회 */ public PostVO search(int postId) throws SQLException { PostVO post = null; Connection con = dataSource.getConnection(); String sql = "select * from post where post_id = ?"; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setInt(1, postId); ResultSet rs = pstmt.executeQuery(); while(rs.next()) { int postId1 = rs.getInt(1); String memberId= rs.getString(2); String postTitle = rs.getString(3); String postContent = rs.getString(4); int readCount = rs.getInt(5); String imgAttachment = rs.getString(6); String dataAttachment = rs.getString(7); Timestamp postDate = rs.getTimestamp(8); post = new PostVO(postId,memberId, postTitle, postContent, readCount, imgAttachment, dataAttachment, postDate); } return post; } }
Criteria.java
public class Criteria { private int currentPage; // 현재 페이지 번호 private int perPageNum; // 한 페이지 당 게시물 개수 // 특정 페이지의 맨 아래 게시물 행번호 (내림차순 기준) public int getPageStart() { return (this.currentPage-1)*perPageNum; } public Criteria() { this.perPageNum = 10; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { if(currentPage <= 0) { this.currentPage = 1; } else { this.currentPage = currentPage; } } public int getPerPageNum() { return perPageNum; } public void setPerPageNum(int pageCount) { int cnt = this.perPageNum; if(pageCount != cnt) { this.perPageNum = cnt; } else { this.perPageNum = pageCount; } } }
Paging.java
public class Paging { private Criteria cri; private int totalCount; // 총 게시물 개수 private int startPage; private int endPage; private boolean prev; // 이전 버튼 private boolean next; // 다음 버튼 private int displayPageNum = 5; // 화면에 띄울 페이지 번호 개수 private void calcData() { endPage = (int) (Math.ceil(cri.getCurrentPage() / (double) displayPageNum) * displayPageNum); // 시작 페이지 번호 startPage = (endPage - displayPageNum) + 1; if(startPage <= 0) { startPage = 1; } // 마지막 페이지 번호 int tempEndPage = (int) (Math.ceil(totalCount / (double) cri.getPerPageNum())); if (endPage > tempEndPage) { endPage = tempEndPage; } // 시작 페이지 번호가 1이면 이전 버튼 비활성화 if(startPage == 1) { prev = false; } else { prev = true; } // (마지막 페이지 번호 * 한 페이지 당 게시물 개수 > 총 게시물 개수)라면 // 다음버튼 비활성화 if(endPage * cri.getPerPageNum() > totalCount) { next = false; } else { next = true; } } public Criteria getCri() { return cri; } public void setCri(Criteria cri) { this.cri = cri; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; calcData(); } public int getStartPage() { return startPage; } public void setStartPage(int startPage) { this.startPage = startPage; } public int getEndPage() { return endPage; } public void setEndPage(int endPage) { this.endPage = endPage; } public boolean isPrev() { return prev; } public void setPrev(boolean prev) { this.prev = prev; } public boolean isNext() { return next; } public void setNext(boolean next) { this.next = next; } public int getDisplayPageNum() { return displayPageNum; } public void setDisplayPageNum(int displayPageNum) { this.displayPageNum = displayPageNum; } }
'프로젝트 일지 > Spring 프로젝트- 헬스 커뮤니티' 카테고리의 다른 글
최종 결과물 - <헬스 커뮤니티> (0) 2023.02.27 3일차 - 게시물 검색 (0) 2023.02.22 1일차(2) - 게시물 목록 (0) 2023.02.20 1일차(1) - 프로젝트 설계 <헬스 커뮤니티> (0) 2023.02.20