게시판 페이지네이션 기능 만들어 줘
ChatGPT의 말:
Eclipse Dynamic Web Project + MySQL 게시판에 페이지네이션 기능을 추가하는 간단한 예제를 보여드릴게요.
서블릿과 JSP 양쪽에서 10개씩 페이지 그룹을 나누는 페이지네이션 으로 구현합니다.
게시판 페이징 기본 개념
- 한 페이지에 보여줄 게시글 수를 정합니다. 예: 10개
- 현재 페이지 번호를 받아서, SQL에서 LIMIT와 OFFSET을 사용해 해당 페이지에 맞는 글을 불러옵니다.
- 전체 게시글 수를 구해서 총 페이지 수를 계산합니다.
- JSP에서 페이지 번호 링크를 출력해 페이지 이동 가능하게 만듭니다.
게시판에서 페이지네이션을 할 때, 총 페이지 개수를 10개씩 묶어서 페이지 네비게이션(페이지 그룹) 으로 보여주려면?
예를 들어, 총 페이지가 35면:
- 1 ~ 10 페이지 그룹
- 11 ~ 20 페이지 그룹
- 21 ~ 30 페이지 그룹
- 31 ~ 35 페이지 그룹 이런 식으로 나누는 거예요.
- pageSize = 10 (한 페이지에 보여줄 게시글 수)
- pageGroupSize = 10 (한번에 보여줄 페이지 링크 개수)
- currentPage = 현재 사용자가 보고 있는 페이지 번호
- totalPages = 전체 페이지 수
1. MySQL 게시글 불러오기 쿼리 수정하기
SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?;
- LIMIT : 한 페이지에 보여줄 글 개수 (예: 10)
- OFFSET : 건너뛸 글 개수 ((page - 1) * limit)
2. 게시글 상세보기
postView
postView는 게시글 상세보기 페이지로, 특정 게시글 ID를 받아서 DB에서 해당 글을 조회해 보여주는 기능입니다.
1. PostViewServlet.java (서블릿)
package controller;
import java.io.IOException;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import dao.BoardDAO;
import model.Post;
@WebServlet("/postView")
public class PostViewServlet extends HttpServlet {
private BoardDAO dao = new BoardDAO();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String idStr = request.getParameter("id");
if (idStr == null || idStr.isEmpty()) {
response.sendRedirect("posts"); // id가 없으면 목록으로 리다이렉트
return;
}
int id = 0;
try {
id = Integer.parseInt(idStr);
} catch (NumberFormatException e) {
response.sendRedirect("posts");
return;
}
try {
Post post = dao.getPostById(id);
if (post == null) {
response.sendRedirect("posts"); // 게시글 없으면 목록으로
return;
}
String pageParam = request.getParameter("page");
int currentPage = 1;
if (pageParam != null) {
try {
currentPage = Integer.parseInt(pageParam);
} catch (NumberFormatException e) {
currentPage = 1;
}
}
request.setAttribute("currentPage", currentPage);
request.setAttribute("post", post);
request.getRequestDispatcher("/postView.jsp").forward(request, response);
} catch (SQLException e) {
throw new ServletException(e);
}
}
}
2. BoardDAO.java에 상세보기 메서드 추가
public Post getPostById(int id) throws SQLException {
String sql = "SELECT * FROM posts WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
Post post = new Post();
post.setId(rs.getInt("id"));
post.setTitle(rs.getString("title"));
post.setContent(rs.getString("content"));
post.setCreatedAt(rs.getTimestamp("created_at"));
return post;
}
return null;
}
}
3. postView.jsp (게시글 상세보기 JSP)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="model.Post" %>
<%
Post post = (Post) request.getAttribute("post");
if (post == null) {
%>
<p>게시글을 찾을 수 없습니다.</p>
<%
} else {
%>
<html>
<head>
<title><%= post.getTitle() %> - 게시글 상세</title>
</head>
<body>
<h2><%= post.getTitle() %></h2>
<p><em>작성일: <%= post.getCreatedAt() %></em></p>
<hr>
<div><pre><%= post.getContent() %></pre></div>
<%
int currentPage = 1;
if (request.getAttribute("currentPage") != null) {
currentPage = (Integer) request.getAttribute("currentPage");
}
%>
<hr>
<!-- 목록으로 가기 버튼 -->
<a href="board?page=<%= currentPage %>">목록으로</a>
</body>
</html>
<%
}
%>
정리
- postView 서블릿에서 id 파라미터 받아서 게시글 조회
- DAO에 getPostById 메서드 추가
- 조회된 게시글을 JSP로 넘겨 상세보기 출력
2. DAO 수정하기
package dao;
import model.Post;
import java.sql.*;
import java.util.*;
public class BoardDAO {
private static final String URL = "jdbc:mysql://localhost:3306/boarddb?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true";
private static final String USER = "root"; // 본인 DB 계정
private static final String PASSWORD = "qwerty!";
private Connection getConn() throws SQLException {
//return DriverManager.getConnection(URL, USER, PASSWORD)
try {
// Load the MySQL JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver"); // Use the appropriate driver class name
return DriverManager.getConnection(URL, USER, PASSWORD);
} catch (Exception e) {
e.printStackTrace(); // Handle any exceptions
}
return null;
}
// 게시글 전체 개수 가져오기
public int getTotalPosts() throws SQLException {
String sql = "SELECT COUNT(*) FROM posts";
try (Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery())
{
if (rs.next()) {
return rs.getInt(1);
}
return 0;
}
}
// 페이징해서 게시글 목록 가져오기
public List<Post> getPostsByPage(int page, int pageSize) throws SQLException {
String sql = "SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?";
try (Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql))
{
pstmt.setInt(1, pageSize);
pstmt.setInt(2, (page - 1) * pageSize);
ResultSet rs = pstmt.executeQuery();
List<Post> posts = new ArrayList<>();
while (rs.next()) {
Post post = new Post();
post.setId(rs.getInt("id"));
post.setTitle(rs.getString("title"));
post.setContent(rs.getString("content"));
post.setCreatedAt(rs.getTimestamp("created_at"));
// 필요한 필드 추가 세팅
posts.add(post);
}
return posts;
}
}
public Post getPostById(int id) throws SQLException {
String sql = "SELECT * FROM posts WHERE id = ?";
try (
Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
Post post = new Post();
post.setId(rs.getInt("id"));
post.setTitle(rs.getString("title"));
post.setContent(rs.getString("content"));
post.setCreatedAt(rs.getTimestamp("created_at"));
return post;
}
return null;
}
}
public List<Post> getPosts(int offset, int limit) throws SQLException {
List<Post> posts = new ArrayList<>();
String sql = "SELECT * FROM posts ORDER BY created_at DESC LIMIT ? OFFSET ?";
try (
Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, limit);
pstmt.setInt(2, offset);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
Post post = new Post();
post.setId(rs.getInt("id"));
post.setTitle(rs.getString("title"));
post.setContent(rs.getString("content"));
post.setCreatedAt(rs.getTimestamp("created_at"));
posts.add(post);
}
}
return posts;
}
public List<Post> getAllPosts() {
List<Post> list = new ArrayList<>();
String sql = "SELECT * FROM posts ORDER BY id DESC";
try (Connection conn = getConn();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
list.add(new Post(
rs.getInt("id"),
rs.getString("title"),
rs.getString("content"),
rs.getTimestamp("created_at") // ← created_at 추가
));
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
public void addPost(String title, String content) {
String sql = "INSERT INTO posts (title, content) VALUES (?, ?)";
try (Connection conn = getConn();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, title);
pstmt.setString(2, content);
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. JSP 수정하기 (list.jsp 예시)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*, model.Post" %>
<%
List<Post> posts = (List<Post>) request.getAttribute("posts");
int currentPage = (Integer) request.getAttribute("currentPage");
int totalPages = (Integer) request.getAttribute("totalPages");
int pageGroupSize = 10;
int currentPageGroup = (int) Math.ceil((double) currentPage / pageGroupSize);
int startPage = (currentPageGroup - 1) * pageGroupSize + 1;
int endPage = Math.min(startPage + pageGroupSize - 1, totalPages);
%>
<html>
<head>
<title>게시판 목록</title>
</head>
<body>
<h2>게시판 목록</h2>
<table border="1" width="600">
<tr>
<th>ID</th><th>제목</th><th>작성일</th>
</tr>
<%
for (Post post : posts) {
%>
<tr>
<td><%= post.getId() %></td>
<td>
<% int currPage = (request.getAttribute("currentPage") != null) ?
(Integer) request.getAttribute("currentPage") : 1;
%>
<a href="postView?id=<%= post.getId() %>&page=<%= currPage %>">
<%= post.getTitle() %></a>
</td>
<td><%= post.getCreatedAt() %></td>
</tr>
<%
}
%>
</table>
<div class="pagination" style="margin-top:20px;">
<% if (startPage > 1) { %>
<a href="board?page=<%= startPage - 1 %>">« 이전</a>
<% } %>
<% for (int i = startPage; i <= endPage; i++) { %>
<% if (i == currentPage) { %>
<strong><%= i %></strong>
<% } else { %>
<a href="board?page=<%= i %>"><%= i %></a>
<% } %>
<% } %>
<% if (endPage < totalPages) { %>
<a href="board?page=<%= endPage + 1 %>">다음 »</a>
<% } %>
</div>
</body>
</html>
'전자정부 프레임워크 공부' 카테고리의 다른 글
전자정부 프레임워크 3.10 - index.jsp (0) | 2025.05.19 |
---|---|
전자정부프레임워크(eGovFrame)의 web.xml 설정 (0) | 2025.05.19 |
게시판 개발용 페이크 데이터 추가하기 [전자정부 프레임워크 공부] (0) | 2025.05.18 |
Dynamic Web Project 게시판 예제 [전자정부 프레임워크 공부] (0) | 2025.05.18 |
Eclipse에서 Dynamic Web Project 기본 예제 [전자정부 프레임워크 공부] (1) | 2025.05.18 |