수백, 수천 개의 글을 전부 한 페이지에 표시할 수는 없다. 특정 개수만큼만 출력하고 다음 페이지를 통해서 또 다른 글들을 보여줘야 한다.

먼저 한 페이지에 들어갈 글 개수를 정하고 이를 조회하는 sql문을 작성해야 한다.
bbs.sql
[페이징]
- rownum 줄번호 활용
1)
SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC;
2) rownum 추가 - 줄번호까지 정렬됨
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC;
3) 1)의 SQL문을 셀프조인하고, rownum 추가
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum
FROM ( SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC
);
4) 줄번호 1~5 조회 (1페이지)
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum
FROM ( SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC
)
WHERE rownum>=1 AND rownum<=5;
5) 줄번호 6~10 조회 (2페이지) -> 조회안됨. 선택된 레코드가 없습니다
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum
FROM ( SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC
)
WHERE rownum>=6 AND rownum<=10;
6) 3)의 테이블을 한번 더 셀프조인하고, rownum 칼럼명을 r로 바꾼다
SELECT *
FROM (
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r
FROM (
SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
ORDER BY grpno DESC, ansnum ASC
)
)
WHERE r>=6 AND r<=10;
7) 페이징 + 검색
예) 제목에서 '파스타'가 있는 행을 검색해서 2페이지(6행~10행)만 조회하시오
SELECT *
FROM (
SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r
FROM (
SELECT bbsno, subject, wname, readcnt, indent, regdt
FROM tb_bbs
WHERE subject LIKE '%파스타%'
ORDER BY grpno DESC, ansnum ASC
)
)
WHERE r>=6 AND r<=10;
BbsDAO.java에서 list3()을 만들어 페이징 기능을 넣도록 한다.
BbsDAO.java
public ArrayList<BbsDTO> list3(String col, String word) {
ArrayList<BbsDTO> list = null;
int startRow = 6;
int endRow = 10;
try {
con = dbopen.getConection();
sql = new StringBuilder();
word = word.trim(); //검색어 좌우 공백 제거
if(word.length()==0) { //검색하지 않는 경우 -> 6)
sql.append(" SELECT * ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt ");
sql.append(" FROM tb_bbs ");
sql.append(" ORDER BY grpno DESC, ansnum ASC ");
sql.append(" ) ");
sql.append(" ) ");
sql.append(" WHERE r>=" + startRow + " AND r<=" + endRow);
} else { //검색하는 경우 -> 7)
sql.append(" SELECT * ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt ");
sql.append(" FROM tb_bbs ");
String search = "";
if(col.equals("subject_content")) {
search += " WHERE subject LIKE '%" + word + "%' ";
search += " OR content LIKE '%" + word + "%' ";
} else if(col.equals("subject")) {
search += " WHERE subject LIKE '%" + word + "%' ";
} else if(col.equals("content")) {
search += " WHERE content LIKE '%" + word + "%' ";
} else if(col.equals("wname")) {
search += " WHERE wname LIKE '%" + word + "%' ";
}//if end
sql.append(search);
sql.append(" ORDER BY grpno DESC, ansnum ASC ");
sql.append(" ) ");
sql.append(" ) ");
sql.append(" WHERE r>=" + startRow + " AND r<=" + endRow);
}//if end
pstmt = con.prepareStatement(sql.toString());
rs = pstmt.executeQuery();
if(rs.next()) {
list = new ArrayList<>();
do {
BbsDTO dto = new BbsDTO(); //한줄담기
dto.setBbsno(rs.getInt("bbsno"));
dto.setWname(rs.getString("wname"));
dto.setSubject(rs.getString("subject"));
dto.setReadcnt(rs.getInt("readcnt"));
dto.setRegdt(rs.getString("regdt"));
dto.setIndent(rs.getInt("indent"));
list.add(dto); //list 저장
} while(rs.next());
}//if end
} catch (Exception e) {
System.out.println("전체목록실패:" + e);
} finally {
DBClose.close(con, pstmt, rs);
}//end
return list;
}//list3() end
이제 페이지 번호를 만들어 한 페이지에 정해진 개수만큼의 글을 보여줘야 한다.

nowPage의 기본값은 1로 처음 게시판에 들어오면 1페이지를 보여주도록 한다.
recordPerPage는 한 페이지에 보여줄 글의 개수이다.
1페이지에서 2페이지, 2페이지에서 3페이지 이렇게 페이지를 변경할 때마다 nowPage값을 가져와야 하니 공통 코드를 모아놓은 ssi.jsp에 nowPage 값을 가져오는 코드를 작성하자
ssi.jsp
//현재페이지 ------------------------------------------------------
int nowPage = 1;
if(request.getParameter("nowPage")!=null) {
nowPage = Integer.parseInt(request.getParameter("nowPage"));
}//if end
BbsDAO.jsp
public ArrayList<BbsDTO> list3(String col, String word, int nowPage, int recordPerPage) {
ArrayList<BbsDTO> list = null;
//페이지당 출력할 행의 갯수(10개를 기준)
//1 페이지 : WHERE r>=1 AND r<=10;
//2 페이지 : WHERE r>=11 AND r<=20;
//3 페이지 : WHERE r>=21 AND r<=30;
int startRow = ((nowPage-1) * recordPerPage) + 1 ;
int endRow = nowPage * recordPerPage;
try {
con = dbopen.getConection();
sql = new StringBuilder();
word = word.trim(); //검색어 좌우 공백 제거
if(word.length()==0) { //검색하지 않는 경우 -> 6)
sql.append(" SELECT * ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt ");
sql.append(" FROM tb_bbs ");
sql.append(" ORDER BY grpno DESC, ansnum ASC ");
sql.append(" ) ");
sql.append(" ) ");
sql.append(" WHERE r>=" + startRow + " AND r<=" + endRow);
} else { //검색하는 경우 -> 7)
sql.append(" SELECT * ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt, rownum as r ");
sql.append(" FROM ( ");
sql.append(" SELECT bbsno, subject, wname, readcnt, indent, regdt ");
sql.append(" FROM tb_bbs ");
String search = "";
if(col.equals("subject_content")) {
search += " WHERE subject LIKE '%" + word + "%' ";
search += " OR content LIKE '%" + word + "%' ";
} else if(col.equals("subject")) {
search += " WHERE subject LIKE '%" + word + "%' ";
} else if(col.equals("content")) {
search += " WHERE content LIKE '%" + word + "%' ";
} else if(col.equals("wname")) {
search += " WHERE wname LIKE '%" + word + "%' ";
}//if end
sql.append(search);
sql.append(" ORDER BY grpno DESC, ansnum ASC ");
sql.append(" ) ");
sql.append(" ) ");
sql.append(" WHERE r>=" + startRow + " AND r<=" + endRow);
}//if end
pstmt = con.prepareStatement(sql.toString());
rs = pstmt.executeQuery();
if(rs.next()) {
list = new ArrayList<>();
do {
BbsDTO dto = new BbsDTO(); //한줄담기
dto.setBbsno(rs.getInt("bbsno"));
dto.setWname(rs.getString("wname"));
dto.setSubject(rs.getString("subject"));
dto.setReadcnt(rs.getInt("readcnt"));
dto.setRegdt(rs.getString("regdt"));
dto.setIndent(rs.getInt("indent"));
list.add(dto); //list 저장
} while(rs.next());
}//if end
} catch (Exception e) {
System.out.println("전체목록실패:" + e);
} finally {
DBClose.close(con, pstmt, rs);
}//end
return list;
}//list3() end

우선 한 페이지에 글이 5개씩 나오도록 만들었다.
아래 이미지는 recordPerPage를 10으로 변경하였을 때의 화면이다.

다음으로 페이지 리스트를 만들어보자
그전에 아래 파일을 받아 net.utility에 넣어두자
bbsList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="ssi.jsp"%>
<%@ include file="../header.jsp"%>
<!-- 본문 시작 bbsLIst.jsp-->
<h3>* 글 목록 *</h3>
<p><a href="bbsForm.jsp">[글쓰기]</a></p>
<div>
<table class="table">
<thead>
<tr class="success">
<th>순번</th>
<th>제목</th>
<th>조회수</th>
<th>작성자</th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<%
//한페이지당 출력할 행의 개수
int recordPerPage = 5;
ArrayList<BbsDTO> list = dao.list3(col, word, nowPage, recordPerPage);
if(list==null){
out.println("<tr>");
out.println(" <td colspan='4'>");
out.println(" <strong>관련자료 없음!!</strong>");
out.println(" </td>");
out.println("</tr>");
} else {
//오늘 날짜를 문자열 "2022-10-22" 만들기
String today = Utility.getDate();
for(int i=0; i<list.size(); i++) {
dto = list.get(i);
%>
<tr>
<td><%=dto.getRownum()%></td>
<td style="text-align: left">
<%
//답변이미지 출력
for(int n=1; n<=dto.getIndent(); n++){
out.println("<img src='../images/reply.gif'>");
}//for end
%>
<a href="bbsRead.jsp?bbsno=<%=dto.getBbsno()%>&col=<%=col%>&word=<%=word%>"><%=dto.getSubject()%></a>
<%
//오늘 작성한 글제목 뒤에 new 이미지 출력
//작성일(regdt)에서 "년월일"만 자르기
String regdt = dto.getRegdt().substring(0, 10);
if(regdt.equals(today)){ //작성일과 오늘 날짜가 같다면
out.println("<img src='../images/new.gif'>");
}//if end
//조회수가 10 이상이면 hot이미지 출력
if(dto.getReadcnt()>=10) {
out.println("<img src='../images/hot.gif'>");
}//if end
%>
</td>
<td><%=dto.getReadcnt()%></td>
<td><%=dto.getWname()%></td>
<td><%=dto.getRegdt().substring(0, 10)%></td>
</tr>
<%
}//for end
//글갯수
int totalRecord = dao.count2(col, word);
out.println("<tr>");
out.println(" <td colspan='4' style='text-align:center;'>");
out.println(" 글갯수:<strong> " + totalRecord + " </strong>");
out.println(" </td>");
out.println("</tr>");
//페이지 리스트
out.println("<tr>");
out.println(" <td colspan='4' style='text-align:center; height: 50px'>");
String paging = new Paging().paging3(totalRecord, nowPage, recordPerPage, col, word, "bbsList.jsp");
out.println(paging);
out.println(" </td>");
out.println("</tr>");
%>
<!-- 검색 시작 -->
<tr>
<td colspan="4" style="text-align:center; height: 50px;">
<form action="bbsList.jsp" onsubmit="return searchCheck()"><!-- myscript.js 함수 작성함 -->
<select name="col">
<option value="subject_content">제목+내용
<option value="subject">제목
<option value="content">내용
<option value="wname">작성자
</select>
<input type="text" name="word" id="word">
<input type="submit" value="검색" class="btn btn-primary">
</form>
</td>
</tr>
<!-- 검색 끝 -->
<%
}//if end
%>
</tbody>
</table>
</div>
<!-- 본문 끝 -->
<%@ include file="../footer.jsp"%>

paging.java
paging1 메서드 설명


특정 페이지에서 글을 상세보기 한 후 다시 목록으로 나오면 원래 있던 페이지로 돌아간다.
예를 들어 3페이지에서 '니벨룽겐'이라는 글을 클릭해 본 후 목록으로 나오면 3페이지로 나온다.
하지만 지금은 3페이지가 아닌 1페이지가 나오므로 3페이지가 나오도록 변경해보자
bbsLisp.jsp
<a href="bbsRead.jsp?bbsno=<%=dto.getBbsno()%>&col=<%=col%>&word=<%=word%>&nowPage=<%=nowPage%>"><%=dto.getSubject()%></a>

bbsRead.jsp
<a href="bbsList.jsp?col=<%=col%>&word=<%=word%>&nowPage=<%=nowPage%>">[글목록]</a>

'웹개발 교육 > jsp' 카테고리의 다른 글
| [55일] jsp (23) - SCOPE (0) | 2022.10.17 |
|---|---|
| [55일] jsp (22) - jsp 내부객체 (0) | 2022.10.17 |
| [53~54일] jsp (20) - myweb 프로젝트(게시판-검색) (0) | 2022.10.13 |
| [53일] jsp (19) - myweb 프로젝트(게시판-답변 쓰기) (0) | 2022.10.13 |
| [51~52일] jsp (18) - myweb 프로젝트(게시판) (0) | 2022.10.11 |