1. 변수 설명
페이지 관련 변수
변수명 | 설명 |
cpage | 현재 페이지 번호 (기본값: 1). |
recordPerPage | 한 페이지에 표시할 데이터 수 (예: 10개). |
blockPerPage | 한 화면에 표시할 페이지 블록 수 (예: 5개). |
totalRecord | 전체 데이터 개수. |
totalPage | 전체 페이지 수 (총 데이터 수를 페이지당 데이터 수로 나눈 값). |
skip | 현재 페이지에서 건너뛸 데이터 수 ((cpage - 1) * recordPerPage). |
2. 계산식 분석
전체 페이지 계산
전체 데이터를 기준으로 필요한 페이지 수를 계산합니다. (totalRecord - 1)로 계산하면 전체 데이터가 recordPerPage로 나누어떨어질 때도 올바른 페이지 수를 얻을 수 있습니다.
totalPage = ((totalRecord - 1) / recordPerPage) + 1;
데이터 건너뛰기
skip 변수는 현재 페이지에서 몇 개의 데이터를 건너뛸지를 계산합니다. 이는 SQL 쿼리의 OFFSET 또는 rs.absolute()를 설정하는 데 사용됩니다.
int skip = (cpage - 1) * recordPerPage;
블록 계산
페이지 번호를 그룹화(블록 처리)하여 현재 페이지가 속한 블록의 시작 번호와 끝 번호를 계산합니다.
- 시작 블록 번호: 현재 페이지를 기준으로 블록의 첫 페이지를 계산.
int startBlock = cpage - (cpage - 1) % blockPerPage;
- 끝 블록 번호: 블록에서 표시할 마지막 페이지를 계산. 전체 페이지 수를 초과하지 않도록 처리.
int endBlock = startBlock + blockPerPage - 1;
if (endBlock > totalPage) {
endBlock = totalPage;
}
3. 구현부
3.1 프로젝트 구조
jspPaging/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── jsppaging/
│ │ │ ├── controller/
│ │ │ │ └── BoardController.java
│ │ │ ├── dao/
│ │ │ │ └── BoardDAO.java
│ │ │ ├── dto/
│ │ │ │ └── BoardDTO.java
│ │ │ ├── mapper/
│ │ │ │ └── BoardMapper.java
│ │ │ └── JspPagingApplication.java
│ │ └── resources/
│ │ ├── application.properties
│ │ ├── mappers/
│ │ │ └── BoardMapper.xml
│ │ └── templates/
│ │ └── board_list1.jsp
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── jsppaging/
│ └── BoardControllerTests.java
├── build.gradle
└── settings.gradle
3.2 application.properties
spring.application.name=jspPaging
# MariadDB 환경 설정
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/test2
spring.datasource.username=board
spring.datasource.password=123456
# JSP 환경 설정
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
# MyBatis 설정
mybatis.mapper-locations=classpath:mappers/*.xml
mybatis.type-aliases-package=com.example.jsppaging.dto
3.3 board_list1.jsp
<%
// 현재 페이지 구하기
int cpage = 1;
if (request.getParameter("cpage") != null && !request.getParameter("cpage").equals("")) {
cpage = Integer.parseInt(request.getParameter("cpage"));
}
// 페이지당 데이터 갯수
int recordPerPage = 10;
// 전체 데이터 개수
int totalRecord = 0;
// 전체 페이지 수
int totalPage = 1;
// 한 화면에 보이는 페이지
int blockPerPage = 5;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
StringBuilder sbHtml = new StringBuilder();
try {
Context initCtx = new InitialContext(); // 컨텍스트 객체 생성
Context envCtx = (Context) initCtx.lookup("java:/comp/env"); // 환경 객체 생성
DataSource dataSource = (DataSource) envCtx.lookup("jdbc/mariadb1"); // 데이터소스 객체 생성
conn = dataSource.getConnection(); // 데이터베이스 연결
String sql = "select seq, subject, writer, date_format(wdate, '%Y/%m/%d') wdate, datediff(now(), wdate) wgap, hit from board1 order by seq desc";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
// 데이터 개수를 얻어내는 방법
rs.last();
totalRecord = rs.getRow();
rs.beforeFirst();
// 전체 페이지 계산
totalPage = ((totalRecord - 1) / recordPerPage) + 1;
// 읽을 위치로 변경
int skip = (cpage - 1) * recordPerPage;
if (skip != 0) rs.absolute(skip);
for (int i = 0; i < recordPerPage && rs.next(); i++) {
// 레코드 컬럼 추출
String seq = rs.getString("seq");
String subject = rs.getString("subject");
String writer = rs.getString("writer");
String wdate = rs.getString("wdate");
String hit = rs.getString("hit");
int wgap = rs.getInt("wgap");
// 테이블 행 추가 전 로그 확인
// System.out.println(seq + " " + subject + " " + writer + " " + wdate + " " + hit);
// 테이블 행 추가
sbHtml.append("<tr>");
sbHtml.append("<td> </td>");
sbHtml.append("<td>" + seq + "</td>");
if (wgap == 0) {
sbHtml.append("<td class='left'><a href='board_view1.jsp?seq=" + seq + "&cpage=" + cpage + "'>" + subject + "</a> <img src='../../images/icon_new.gif' alt='NEW'></td>");
} else {
sbHtml.append("<td class='left'><a href='board_view1.jsp?seq=" + seq + "&cpage=" + cpage + "'>" + subject + "</a></td>");
}
sbHtml.append("<td>" + writer + "</td>");
sbHtml.append("<td>" + wdate + "</td>");
sbHtml.append("<td>" + hit + "</td>");
sbHtml.append("<td> </td>");
sbHtml.append("</tr>");
}
} catch (NamingException e) {
System.out.println("[에러] " + e.getMessage());
} catch (SQLException e) {
System.out.println("[에러] " + e.getMessage());
} finally {
try {
rs.close();
} catch (SQLException e) {
}
try {
pstmt.close();
} catch (SQLException e) {
}
try {
conn.close();
} catch (SQLException e) {
}
}
%>
<!-- 생략... -->
<!--페이지넘버-->
<div class="paginate_regular">
<div align="absmiddle">
<%
// 현재 블록의 시작 페이지 계산
int startBlock = cpage - (cpage - 1) % blockPerPage;
// 현재 블록의 끝 페이지 계산
int endBlock = startBlock + (blockPerPage - 1);
// 블록의 끝 페이지가 전체 페이지를 초과하지 않도록 설정
if (endBlock >= totalPage) {
endBlock = totalPage;
}
// 이전 블록으로 이동 링크 출력
if (cpage <= blockPerPage) {
// 첫 번째 블록일 경우 '<<' 링크 비활성화
out.println("<span><a><<</a></span>");
} else {
// 이전 블록으로 이동 ('<<')
out.println("<span><a href='board_list1.jsp?cpage=" + (startBlock - blockPerPage) + "'><<</a></span>");
}
out.println(" ");
// 이전 페이지로 이동 링크 출력
if (cpage == 1) {
// 첫 번째 페이지일 경우 '<' 링크 비활성화
out.println("<span><a><</a></span>");
} else {
// 이전 페이지로 이동 ('<')
out.println("<span><a href='board_list1.jsp?cpage=" + (cpage - 1) + "'><</a></span>");
}
out.println(" ");
// 현재 블록 내 페이지 번호 출력
for (int i = startBlock; i <= endBlock; i++) {
if (i == cpage) {
// 현재 페이지는 강조 표시
out.println("<span><a>[" + i + "]</a></span>");
} else {
// 다른 페이지로 이동 링크
out.println("<span><a href='board_list1.jsp?cpage=" + i + "'>" + i + "</a></span>");
}
}
out.println(" ");
// 다음 페이지로 이동 링크 출력
if (cpage == totalPage) {
// 마지막 페이지일 경우 '>' 링크 비활성화
out.println("<span><a>></a></span>");
} else {
// 다음 페이지로 이동 ('>')
out.println("<span><a href='board_list1.jsp?cpage=" + (cpage + 1) + "'>></a></span>");
}
out.println(" ");
// 다음 블록으로 이동 링크 출력
if (endBlock == totalPage) {
// 마지막 블록일 경우 '>>' 링크 비활성화
out.println("<span><a>>></a></span>");
} else {
// 다음 블록으로 이동 ('>>')
out.println("<span><a href='board_list1.jsp?cpage=" + (startBlock + blockPerPage) + "'>>></a></span>");
}
%>
%>
</div>
</div>
<!--//페이지넘버-->
게시판에서 현재 페이지 정보(cpage)를 가지고, 오류가 발생하지 않게 테스트.
- board_list: 현재 페이지에서 게시판 목록을 보여주는 페이지.
- board_write: 새로운 게시글 작성 페이지.
- board_write_ok: 작성 완료 후 게시판 목록으로 이동.
- board_view: 특정 게시글을 보여주는 페이지.
- board_modify: 게시글 수정 페이지.
- board_modify_ok: 수정 완료 후 특정 게시글 보기로 이동.
- board_delete: 게시글 삭제 확인 페이지.
- board_delete_ok: 삭제 완료 후 게시판 목록으로 이동.
- 페이지 이동 흐름:
- 각 페이지 이동 시 cpage 정보가 유지되도록 설계.
- board_list로 돌아올 때 항상 cpage 값을 포함.
'Spring' 카테고리의 다른 글
SpringBoot 웹 애플리케이션의 MVC 패턴 (0) | 2024.12.20 |
---|---|
답글이 있는 게시판 만들기 (1) | 2024.12.20 |
MVC 패턴이란? (2) | 2024.12.19 |
Spring Web MVC - Http 요청 (0) | 2024.12.19 |
Spring Boot Web 프로젝트에서 JSP 적용하기 (0) | 2024.12.19 |