지난 게시글은 여기 >>
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(15) - 조회수를 증가시키는 부가옵션 만들기
요즘 트랜드야 스크롤을 내리면 계속 글이 서치되어 나오는 것이 트랜드지만 우리는 간단한(?) 블로그를 만드는 거기 때문에 페이징 버튼을 만들자.
이런거
이걸 하려면 우선 어떻게 해야하나? 로직을 생각해보자.
처음에 게시글을 n개만 가져온다. next를 누르면 다음 게시글 n개를 가져온다. 다음 게시글을 누르면 다음 게시글 n개를 가져온다..
이걸 3개라 치면 처음에는 게시판 번호 1~3까지, 다음은 4~6까지, 다음으 7~9까지.. 이렇게 쭉쭉쭉 넘어가야한다. 이걸 나누는 기준은 페이지가 될 것이다.
그럼? 페이지를 get 방식으로 가져가서, 이걸 파라메터로 받아서 게시글에 넣으면 되지.
처음 index에서 uri를 수정하자.
-index.jsp
<%
//response.sendRedirect("/blog/board?cmd=home");
%>
<c:redirect url="/board?cmd=home" />
<c:redirect url="/board?cmd=home&page=0" />
이제 이걸로 home에 접근할때 page 파라메터를 가져갈 수 있게 됐다.
기존의 findAll 함수에 페이지를 넣어서 값을 도출할 수 있는 함수를 새로 만들자.
- BoardHomeAction.java
int page=Integer.parseInt(request.getParameter("page"));
BoardRepository boardRepository = BoardRepository.getInstance();
// 2. 세 건만 페이징해서 가져오기
List<Board> boards = boardRepository.findAll(page);
- BoardRepository.java의 findAll(page) 부분
public List<Board> findAll(int page) {
StringBuilder sb=new StringBuilder();
sb.append("select /*+ INDEX_DESC(BOARD SYS_C008232)*/id, userid, title, content, readcount, createdate ");
sb.append("FROM board ");
sb.append("OFFSET ? ROWS FETCH NEXT 3 ROWS ONLY");
final String SQL=sb.toString();
List<Board> boards=new ArrayList<>();
try {
conn=DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
//물음표 완성하기
pstmt.setInt(1, page*3);
rs=pstmt.executeQuery();
//while
while(rs.next()) {
Board board=new Board(
rs.getInt("id"),
rs.getInt("userId"),
rs.getString("title"),
rs.getString("content"),
rs.getInt("readCount"),
rs.getTimestamp("createDate")
);
boards.add(board);
}
return boards;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG+"findAll : "+e.getMessage());
}finally {
DBConn.close(conn, pstmt);
}
return null;
}
여기서 좀 주의할 점이, 필자는 오라클을 이용하기 때문에 fetch 함수를 썼지만, mySQL을 쓰는 사람은 limit 함수를 써야한다.
이러면 간단하게 세 개만 뽀려지게 된다.
이제 home만 간단하게 수정하면
- home.jsp
<%@page import="com.cos.blog.model.Users"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="include/nav.jsp" %>
<div class="container">
<c:forEach var="board" items="${boards}">
<div class="card m-2" style="width:100%">
<div class="card-body">
<h4 class="card-title">${board.title}</h4>
<p class="card-text">${board.content}</p>
<a href="/blog/board?cmd=detail&id=${board.id }" class="btn btn-primary">상세보기</a>
</div>
</div>
</c:forEach>
<br/>
<ul class="pagination justify-content-center">
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page-1 }">Previous</a></li>
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page+1 }">Next</a></li>>
</ul>
</div>
<%@ include file="include/footer.jsp" %>
이러면 예쁜 버튼이 완성되지만, 문제가 있다.
맨 처음 페이지는 앞으로 돌아가는 버튼이 비활성화되어있어야 하고, 맨 뒤 페이지는 다음으로 가는 버튼이 비활성화 되어 있어야 한다.
맨 앞 페이지에서의 버튼 제어는 간단하다. index에서 날아온 파라메터가 page==0 이면 맨 첫 페이지니까 이 때의 값을 if문으로 분기한다.
분기된 조건의 버튼에는 class 에 disabled 속성을 추가하면 손쉽게 비활성화 할 수 있다.
(앞서 계속 말씀드리지만 필자는.. 부트스트랩을 이용합니다.)
-prev가 수정된 home.jsp
<ul class="pagination justify-content-center">
<c:choose>
<c:when test="${param.page==0 }">
<li class="page-item disabled"><a class="page-link" href="/blog/board?cmd=home&page=${param.page-1 }">Previous</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page-1 }">Previous</a></li>
</c:otherwise>
</c:choose>
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page+1 }">Next</a></li>
</ul>
그럼 마지막은 어떻게 해야할까? 잘 생각해보자.
전체 게시글이 20개다. 그럼 페이지는 몇개여야 하지? 꽉 찬 페이지가 20개를 3으로 나누어 8개, 그리고 2개만 있는 페이지 1개. 총 9개가 있어야 한다. 이런 방식으로 수학적 로직을 짜야한다.
일단 그러면 게시글의 전체 갯수를 카운팅하는 함수가 있어야겠다.
상세보기에서 이걸 뿌릴테니, 이걸 상세보기 함수에서 불러와야겠다.
- BoardHomeAction.java 에서 카운팅 함수 추가
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. DB연결해서 Board 목록 다 불러와서
int page=Integer.parseInt(request.getParameter("page"));
BoardRepository boardRepository = BoardRepository.getInstance();
List<Board> boards = boardRepository.findAll();
// 2. 세 건만 페이징해서 가져오기
List<Board> boards = boardRepository.findAll(page);
int totalCount=boardRepository.countAll();
// 본문 짧게 가공하기
for (Board board : boards) {
@@ -29,6 +33,7 @@ public void execute(HttpServletRequest request, HttpServletResponse response) th
}
request.setAttribute("boards", boards);
request.setAttribute("totalCount", totalCount);
RequestDispatcher dis =
request.getRequestDispatcher("home.jsp");
- home.jsp 에서 페이지 함수 추가
</div>
</c:forEach>
<br/>
<ul class="pagination justify-content-center">
<c:choose>
<c:when test="${param.page==0 }">
<li class="page-item disabled"><a class="page-link" href="/blog/board?cmd=home&page=${param.page-1 }">Previous</a></li>
</c:when>
<c:otherwise>
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page-1 }">Previous</a></li>
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${param.page<=totalCount/3-1}">
<li class="page-item"><a class="page-link" href="/blog/board?cmd=home&page=${param.page+1 }">Next</a></li>
</c:when>
<c:otherwise>
<li class="page-item disabled"><a class="page-link" href="/blog/board?cmd=home&page=${param.page+1 }">Next</a></li>
</c:otherwise>
</c:choose>
</ul>
</div>
<%@ include file="include/footer.jsp" %>
페이지가 0에서 시작하므로 토탈카운트에서 /3하고 -1을 해야 페이지의 마지막 장을 가져올 수 있다.
다음과 같이 페이징이 가능하고, 블로그의 맨 앞장이나 맨 뒷장에 버튼을 비활성화 할 수 있다.
'JSP' 카테고리의 다른 글
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(18) - 키워드를 이용한 검색 만들기 (0) | 2020.06.12 |
---|---|
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(17) - 쿠키를 이용한 새로고침 시 조회수 무한 증가 방어 (0) | 2020.06.12 |
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(15) - 조회수를 증가시키는 부가옵션 만들기 (0) | 2020.06.11 |
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(14) - 해시 함수를 이용해서 비밀번호 해싱하기 (0) | 2020.06.11 |
Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(13) - iframe과 파싱을 이용해 유튜브 파싱하기 (0) | 2020.06.10 |