반응형
1. DAO 수정
- 매개변수를 이용해서 페이지별 목록의 범위를 계산했으니, DAO에서 이를 적용한 쿼리문을 실행한 결과를 반환하면 됨
- BoardDAO 클래스에 게시글 목록을 반환하는 메소드 추가 → selectList() 메소드 아래에 작성
//Java Resources/src/model1/board/BoardDAO.java
... 생략 ...
public class BoardDAO extends JDBConnect {
... 생략 ...
public List<BoardDTO> selectList(Map<String, Object>map) {
... 생략 ...
}
//검색 조건에 맞는 게시물 목록 반환(페이징 기능 지원)
public List<BoardDTO> selectListPage(Map<String, Object>map) {
List<BoardDTO> bbs = new Vector<BoardDTO>(); //결과(게시물 목록)를 담을 변수
//1.쿼리문 템플릿
String query = " SELECT * FROM ( "
+ " SELECT Tb.*, ROWNUM rNum FROM ( "
+ " SELECT * FROM board ";
//2.검색 조건 추가
if (map.get("searchWord") != null) {
query += " WHERE " + map.get("searchField")
+ " LIKE '%" + map.get("searchWord") + "%' ";
}
query += " ORDER BY num DESC "
+ " ) Tb "
+ " ) "
+ " WHERE rNum BETWEEN ? AND ?"; //3.
try {
//4.쿼리문 완성
psmt = con.prepareStatement(query);
psmt.setString(1, map.get("start").toString());
psmt.setString(2, map.get("end").toString());
//5.쿼리문 실행
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.getString("postdate"));
dto.setId(rs.getString("id"));
dto.setVisitcount(rs.getString("visitcount"));
//반환할 결과 목록에 게시물 추가
bbs.add(dto);
}
} catch (Exception e) {
System.out.println("게시물 조회 중 예외 발생");
e.printStackTrace();
}
//목록 반환
return bbs;
}
... 생략 ...
}
- 앞 절에서 설명한 rownum을 이용한 쿼리문 작성(쿼리문 템플릿)
- 검색어가 있다면 WHERE절이 추가되도록 if문을 중간에 추가(검색 조건 추가)
- 시작 게시물과 끝 게시물을 정하는 BETWEEN 부분을 인파라미터로 설정
- 시작과 끝 파라미터를 매개변수로 받은 값으로 채움(=쿼리문 완성)
- 쿼리문 실행
2. List.jsp 수정
1) 페이징 설정값 정의: web.xml에 코드 추가
- 한 페이지에 출력할 게시물의 개수, 한 화면에 출력할 페이지 번호의 개수 설정 → 각각 POSTS_PER_PAGE/PAGES_PER_BLOCK으로, 둘 다 페이지나 페이지 블록을 계산할 때 사용
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi= ... 생략 ...>
... 생략 ...
<context-param>
<param-name>POSTS_PER_PAGE</param-name>
<param-value>10</param-value>
</context-param>
<context-param>
<param-name>POSTS_PER_BLOCK</param-name>
<param-value>5</param-value>
</context-param>
</web-app>
2) 데이터 계산
- 앞서 작성했던 List.jsp에서, selectCount()와 selectListPage() 메소드 사이에 코드 추가
// WebContent/PagingBoard/List.jsp
<%@ page import="java.util.List"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<%@ page import="model1.board.BoardDAO"%>
<%@ page import="model1.board.BoardDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
... 생략 ...
int totalCount = dao.selectCount(param); //게시물 수 확인
/***페이지 처리 start***/
//1.전체 페이지 수 계산
int pageSize = Integer.parseInt(application.getInitParameter("POSTS_PER_PAGE"));
int blockPage = Integer.parseInt(application.getInitParameter("POSTS_PER_BLOCK"));
int totalPage = (int)Math.ceil((double)totalCount / pageSize); //전체 페이지 수
//2.현재 페이지 확인
int pageNum = 1; //기본값
String pageTemp = request.getParameter("pageNum");
if (pageTemp != null && !pageTemp.equals(""))
pageNum = Integer.parseInt(pageTemp); //요청받은 페이지로 수정
//3.목록에 출력할 게시물 범위 계산
int start = (pageNum - 1) * pageSize + 1; //첫 게시물 번호
int end = pageNum * pageSize; //마지막 게시물 번호
param.put("start", start);
param.put("end", end);
/***페이지 처리 end***/
List<BoardDTO> boardLists = dao.selectListPage(param); //4.게시물 목록 받기
dao.close(); //DB 연결 닫기
%>
<!DOCTYPE html>
<html>
<head>
... 생략 ...
- 앞에서 상수로 정의한 설정값을 가져와 전체 페이지 수 계산 (계산 결과가 나누어 떨어지지 않으면, 무조건 올림 처리)
- 현재 페이지 번호 처리: 처음에는 무조건 1로 설정, 매개변수로 페이지 번호가 넘어오면 그 번호를 사용
- 목록에 출력할 게시물의 범위를 계산하여 Map 컬렉션에 저장
- DAO에 새로 추가했던 selectListPage() 메소드를 호출하여, 범위에 해당하는 게시물 목록을 가져옴
3) 바로가기 HTML 코드 생성, 화면 출력
- 목록에 출력할 게시물을 가져왔으니 화면에 출력함
(1) 바로가기 HTML 코드 생성
- 페이지 바로가기 영역을 HTML 문자열로 출력해주는 메소드 구현 (BoardPage.java 파일에 코드 작성)
// Java Resources/src/utils/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))); //1.
//단계 4: '이전 페이지 블록 바로가기' 출력
int pageTemp = (((pageNum -1) / blockPage) * blockPage) + 1;
if (pageTemp != 1) { //2.
pagingStr += "<a href='" + reqUrl + "?pageNum=1'>[첫 페이지]</a>"; //3.
pagingStr += " ";
pagingStr += "<a herf='" + reqUrl + "?pageNum=" + (pageTemp -1)
+"'>[이전 블록]</a>"; //4.
}
//단계 5: 각 페이지 번호 출력
int blockCount = 1;
while (blockCount <= blockPage && pageTemp <= totalPages) {
if (pageTemp == pageNum) { //5.
//현재 페이지는 링크를 걸지 않음
pagingStr += " " + pageTemp + " ";
} else {
pagingStr += " <a href='" + reqUrl + "?pageNum=" + pageTemp
+ "'>" + pageTemp + "</a> "; //6.
}
pageTemp++; //7.
blockCount++;
}
//단계 6: '다음 페이지 블록 바로가기' 출력
if (pageTemp <= totalPages) { //8.
pagingStr += "<a href'" + reqUrl + "?pageNum=" + pageTemp
+ "'>[다음 블록]</a>"; //9.
pagingStr += " ";
pagingStr += "<a href='" + reqUrl + "?pageNum=" + totalPages
+ "'>[마지막 페이지]</a>"; //10.
}
return pagingStr;
}
}
- 전체 페이지 수 계산
- pageTemp가 1이 아닐 때
- [첫 페이지] 바로가기 링크 출력 - pageNum=1
- [이전 블록] 바로가기 링크 출력 - 현재 6페이지일 경우 pageNum=5
- 현재 페이지에서는 링크를 걸지 않기 위해 조건식 사용
- 페이지 바로가기
- pageTemp를 1씩 증가시키며 6.출력
- pageTemp가 전체 페이지 수 이하일 때
- [다음 블록] 바로가기 링크 출력
- [마지막 페이지] 바로가기 링크 출력 (마지막 페이지가 포함된 블록으로 이동하면 이 영역은 출력되지 않음)
→ pageNum 값으로 전체 페이지 수 사용
(2) 화면 출력
- List.jsp 파일의 코드 수정
// WebContent/PagingBoard/List.jsp
<%@ page import="java.util.List"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<%@ page import="model1.board.BoardDAO"%>
<%@ page import="model1.board.BoardDTO"%>
<%@ page import="utils.BoardPage"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
... 생략 ...
<body>
<!-- 1. -->
<h2>목록 보기(List) - 현재 페이지: <%= pageNum %> (전체: <%= totalPage %>)</h2>
... 생략 ...
<!-- 게시물 목록 출력 -->
<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 virtualNumber = 0; //화면상에서의 게시물 번호
int countNum = 0;
for (BoardDTO dto : boardLists) {
//virtualNum = totalCount--; //기존 코드
irtualNum = totalCount - (((pageNum - 1) * pageSize) + countNum++); //2.
%>
<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> <!-- 3. -->
<%= BoardPage.pagingStr(totalCount, pageSize,
blockPage, pageNum, request.getRequestURI()) %>
</td>
<!-- 글쓰기 버튼 -->
<td>
<button type="button" onclick="location.href='Write.jsp';">글쓰기</button>
</td>
</tr>
</table>
</body>
</html>
- 제목에 현재 페이지 번호와 총 페이지 수를 출력
- 목록 출력 시 사용할 가상 번호 계산
→ 페이지에 따라 출력되는 게시물 범위가 다르므로, 가상 번호에도 페이지 번호가 적용되어 계산되어야 함- 전체 게시물 수(totalCount): 106개
- 페이지 범위(pageSize): 10
- 1페이지일 때
- 첫 번째 게시물: 106 - (((1 - 1) * 10) + 0) = 106
- 두 번째 게시물: 106 - (((1 - 1) * 10) + 1) = 106
- 2페이지일 때
- 첫 번째 게시물: 106 - (((2 - 1) * 10) + 0) = 96
- 두 번째 게시물: 106 - (((2 - 1) * 10) + 1) = 95
- 페이지 바로가기 영역 HTML 문자열 출력 메소드 호출
→ 매개변수는 왼쪽부터 ‘전체 게시물 개수’, ‘페이지 범위’, ‘현재 페이지 번호’, ‘실행된 목록 파일명’
3. 동작 확인
- 페이지 기능이 추가된 게시판을 실행한 결과 확인
1) [Run As] → [Run On Server]를 클릭하여 List.jsp 파일 실행
- 첫 실행 시 pageNum 매개변수가 전달되지 않으니 1페이지로 인식함
→ 이전 블록도 없기 때문에, 아무것도 출력되지 않음
2) [다음 블록] 바로가기 링크 클릭
- 현재 페이지 블록의 크기를 5로 설정하였으므로, 다음 블록은 6
- 매개변수로 pageNum=6이 전달되는 것을 볼 수 있고, 게시물도 55번(105 - 50)이 첫 번째로 출력됨
- 첫 페이지가 아니므로 [이전 블록] 바로가기 링크도 출력됨
반응형
'자바(JAVA) > JSP 웹 프로그래밍 공부 (성낙현의 JSP 자바 웹 프로그래밍 참고)' 카테고리의 다른 글
JAVA/JSP 31. 표현 언어(EL: Expression Language) - 컬렉션 사용하기, EL의 연산자들 (3) | 2025.04.18 |
---|---|
JAVA/JSP 30. 표현 언어(EL: Expression Language) - 표현 언어의 정의, EL의 내장 객체 (7) | 2025.04.17 |
JAVA/JSP 28. 회원제 게시판에 페이징 기능 추가 - 페이징이 필요한 이유, 페이징 구현 절차 (2) | 2025.04.15 |
JAVA/JSP 27. 모델1 방식의 회원제 게시판 만들기 - 게시글 삭제하기 (0) | 2024.01.10 |
JAVA/JSP 26. 모델1 방식의 회원제 게시판 만들기 - 게시글 수정하기 (1) | 2024.01.05 |