각 페이지에서 출력할 게시물의 범위
전체 페이지수
'이전 페이지 블록 바로가기'출력
WriteProcess.jsp
// 더미 데이터를 삽입하기 위한 코드
int iResult = 0;
for (int i = 1; i <= 100; i++) {
dto.setTitle(title + "-" + i);
iResult = dao.insertWrite(dto);
}
오라클에서 모든 테이블에서 사용할 수 있는 가상의 컬럼으로,
SELECT 쿼리문으로 추출하는 데이터에 순차적으로 부여되는 순번을 말함.
SELECT * FROM (
SELECT Tb.*, rownum rNum FROM (
SELECT * FROM board ORDER BY num DESC
) Tb
)
WHERE rNUM BETWEEN 1 and 10;
BoardDAO.java
// 검색 조건에 맞는 게시물 목록을 반환합니다(페이징 기능 지원).
public List<BoardDTO> selectListPage(Map<String, Object> map) {
List<BoardDTO> bbs = new Vector<BoardDTO>(); // 결과(게시물 목록)를 담을 변수
// 쿼리문 템플릿
String query = " SELECT * FROM ( "
+ " SELECT Tb.*, ROWNUM rNum FROM ( "
+ " SELECT * FROM board ";
// 검색 조건 추가
if (map.get("searchWord") != null) {
query += " WHERE " + map.get("searchField")
+ " LIKE '%" + map.get("searchWord") + "%' ";
}
query += " ORDER BY num DESC "
+ " ) Tb "
+ " ) "
+ " WHERE rNum BETWEEN ? AND ?";
try {
// 쿼리문 완성
psmt = con.prepareStatement(query);
psmt.setString(1, map.get("start").toString());
psmt.setString(2, map.get("end").toString());
// 쿼리문 실행
rs = psmt.executeQuery();
while (rs.next()) {
// 한 행(게시물 하나)의 데이터를 DTO에 저장
BoardDTO dto = new BoardDTO();
dto.setNum(rs.getString("num"));
dto.setTitle(rs.getString("title"));
dto.setContent(rs.getString("content"));
dto.setPostdate(rs.getDate("postdate"));
dto.setId(rs.getString("id"));
dto.setVisitcount(rs.getString("visitcount"));
// 반환할 결과 목록에 게시물 추가
bbs.add(dto);
}
}
catch (Exception e) {
System.out.println("게시물 조회 중 예외 발생");
e.printStackTrace();
}
// 목록 반환
return bbs;
}
web.xml
<!-- 게시판 페이징 처리를 위한 설정값(예제 9-3) -->
<context-param>
<param-name>POSTS_PER_PAGE</param-name>
<param-value>10</param-value>
</context-param>
<context-param>
<param-name>PAGES_PER_BLOCK</param-name>
<param-value>5</param-value>
</context-param>
List.jsp
/*** 페이지 처리 start ***/
// 전체 페이지 수 계산
int pageSize = Integer.parseInt(application.getInitParameter("POSTS_PER_PAGE"));
int blockPage = Integer.parseInt(application.getInitParameter("PAGES_PER_BLOCK"));
int totalPage = (int)Math.ceil((double)totalCount / pageSize); // 전체 페이지 수
// 현재 페이지 확인
int pageNum = 1; // 기본값
String pageTemp = request.getParameter("pageNum");
if (pageTemp != null && !pageTemp.equals(""))
pageNum = Integer.parseInt(pageTemp); // 요청받은 페이지로 수정
// 목록에 출력할 게시물 범위 계산
int start = (pageNum - 1) * pageSize + 1; // 첫 게시물 번호
int end = pageNum * pageSize; // 마지막 게시물 번호
param.put("start", start);
param.put("end", end);
/*** 페이지 처리 end ***/
BoardPage.java
package utils;
public class BoardPage {
public static String pagingStr(int totalCount, int pageSize, int blockPage,
int pageNum, String reqUrl) {
String pagingStr = "";
// 단계 3 : 전체 페이지 수 계산
int totalPages = (int) (Math.ceil(((double) totalCount / pageSize)));
// 단계 4 : '이전 페이지 블록 바로가기' 출력
int pageTemp = (((pageNum - 1) / blockPage) * blockPage) + 1;
if (pageTemp != 1) {
pagingStr += "<a href='" + reqUrl + "?pageNum=1'>[첫 페이지]</a>";
pagingStr += " ";
pagingStr += "<a href='" + reqUrl + "?pageNum=" + (pageTemp - 1)
+ "'>[이전 블록]</a>";
}
// 단계 5 : 각 페이지 번호 출력
int blockCount = 1;
while (blockCount <= blockPage && pageTemp <= totalPages) {
if (pageTemp == pageNum) {
// 현재 페이지는 링크를 걸지 않음
pagingStr += " " + pageTemp + " ";
} else {
pagingStr += " <a href='" + reqUrl + "?pageNum=" + pageTemp
+ "'>" + pageTemp + "</a> ";
}
pageTemp++;
blockCount++;
}
// 단계 6 : '다음 페이지 블록 바로가기' 출력
if (pageTemp <= totalPages) {
pagingStr += "<a href='" + reqUrl + "?pageNum=" + pageTemp
+ "'>[다음 블록]</a>";
pagingStr += " ";
pagingStr += "<a href='" + reqUrl + "?pageNum=" + totalPages
+ "'>[마지막 페이지]</a>";
}
return pagingStr;
}
}
List.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원제 게시판</title>
</head>
<body>
<jsp:include page="../Common/Link.jsp" /> <!-- 공통 링크 -->
<h2>목록 보기(List) - 현재 페이지 : <%= pageNum %> (전체 : <%= totalPage %>)</h2>
<!-- 검색폼 -->
<form method="get">
<table border="1" width="90%">
<tr>
<td align="center">
<select name="searchField">
<option value="title">제목</option>
<option value="content">내용</option>
</select>
<input type="text" name="searchWord" />
<input type="submit" value="검색하기" />
</td>
</tr>
</table>
</form>
<!-- 게시물 목록 테이블(표) -->
<table border="1" width="90%">
<!-- 각 칼럼의 이름 -->
<tr>
<th width="10%">번호</th>
<th width="50%">제목</th>
<th width="15%">작성자</th>
<th width="10%">조회수</th>
<th width="15%">작성일</th>
</tr>
<!-- 목록의 내용 -->
<%
if (boardLists.isEmpty()) {
// 게시물이 하나도 없을 때
%>
<tr>
<td colspan="5" align="center">
등록된 게시물이 없습니다^^*
</td>
</tr>
<%
}
else {
// 게시물이 있을 때
int virtualNum = 0; // 화면상에서의 게시물 번호
int countNum = 0;
for (BoardDTO dto : boardLists)
{
// virtualNumber = totalCount--; // 전체 게시물 수에서 시작해 1씩 감소
virtualNum = totalCount - (((pageNum - 1) * pageSize) + countNum++);
%>
<tr align="center">
<td><%= virtualNum %></td> <!--게시물 번호-->
<td align="left"> <!--제목(+ 하이퍼링크)-->
<a href="View.jsp?num=<%= dto.getNum() %>"><%= dto.getTitle() %></a>
</td>
<td align="center"><%= dto.getId() %></td> <!--작성자 아이디-->
<td align="center"><%= dto.getVisitcount() %></td> <!--조회수-->
<td align="center"><%= dto.getPostdate() %></td> <!--작성일-->
</tr>
<%
}
}
%>
</table>
<!--목록 하단의 [글쓰기] 버튼-->
<table border="1" width="90%">
<tr align="center">
<!--페이징 처리-->
<td>
<%= BoardPage.pagingStr(totalCount, pageSize,
blockPage, pageNum, request.getRequestURI()) %>
</td>
<!--글쓰기 버튼-->
<td><button type="button" onclick="location.href='Write.jsp';">글쓰기
</button></td>
</tr>
</table>
</body>
</html>