페이지를 글 목록 수에 따라서 나누려고 한다.
DB에서 글을 임의로 늘렸고 페이지당 항목 수도 10 15 20 30으로 정할 수 있게 만들었다.
package com.KoreaIT.java.jsp_AM.servlet;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import com.KoreaIT.java.jsp_AM.util.DBUtil;
import com.KoreaIT.java.jsp_AM.util.SecSql;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/article/list")
public class ArticleListServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 페이지 번호와 페이지당 항목 수 파라미터
int page = 1;
int pageSize = 20; // 기본값
String pageParam = request.getParameter("page");
if (pageParam != null && !pageParam.isEmpty()) {
try {
page = Integer.parseInt(pageParam);
} catch (NumberFormatException e) {
page = 1; // 기본값
}
}
String pageSizeParam = request.getParameter("pageSize");
if (pageSizeParam != null && !pageSizeParam.isEmpty()) {
try {
pageSize = Integer.parseInt(pageSizeParam);
} catch (NumberFormatException e) {
pageSize = 20; // 기본값
}
}
// DB 연결
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("클래스 x");
e.printStackTrace();
}
response.getWriter().append("123");
String url = "jdbc:mysql://127.0.0.1:3306/AM_JDBC_2024_07?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul";
String user = "root";
String password = "1234";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
response.getWriter().append("연결 성공!");
// 페이징 쿼리
int offset = (page - 1) * pageSize;
SecSql sql = SecSql.from("SELECT *");
sql.append("FROM article");
sql.append("ORDER BY id DESC");
sql.append("LIMIT ?", pageSize);
sql.append("OFFSET ?", offset);
List<Map<String, Object>> articleRows = DBUtil.selectRows(conn, sql);
// 전체 게시물 수를 구하는 쿼리
SecSql countSql = SecSql.from("SELECT COUNT(*) AS total FROM article");
int totalCount = DBUtil.selectRowIntValue(conn, countSql);
// 총 페이지 수
int totalPages = (int) Math.ceil(totalCount / (double) pageSize);
request.setAttribute("articleRows", articleRows);
request.setAttribute("currentPage", page);
request.setAttribute("totalPages", totalPages);
request.setAttribute("currentPageSize", pageSize);
request.setAttribute("pageSizes", new int[]{10, 15, 20, 30});
request.getRequestDispatcher("/jsp/article/list.jsp").forward(request, response);
} catch (SQLException e) {
System.out.println("에러 1 : " + e);
} finally {
try {
if (conn != null && !conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
서블릿은 이렇게 수정했고 JSP는
<%@page import="java.util.List"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
List<Map<String, Object>> articleRows = (List<Map<String, Object>>) request.getAttribute("articleRows");
int currentPage = (Integer) request.getAttribute("currentPage");
int totalPages = (Integer) request.getAttribute("totalPages");
int currentPageSize = (Integer) request.getAttribute("currentPageSize");
int[] pageSizes = (int[]) request.getAttribute("pageSizes");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시물 목록</title>
</head>
<body>
<h2>게시물 목록</h2>
<a href="../home/main">메인 페이지로 </a>
<!-- 페이지개수 정하기 -->
<form method="get" action="">
<label for="pageSize">페이지당 항목 수:</label>
<select id="pageSize" name="pageSize" onchange="this.form.submit()">
<% for (int size : pageSizes) { %>
<option value="<%= size %>" <%= (size == currentPageSize) ? "selected" : "" %>><%= size %></option>
<% } %>
</select>
</form>
<table style="border-collapse: collapse; border-color: green;"
border="1px">
<thead>
<tr>
<th>번호</th>
<th>날짜</th>
<th>제목</th>
<th>내용</th>
<th>삭제</th>
</tr>
</thead>
<tbody>
<%
for (Map<String, Object> articleRow : articleRows) {
%>
<tr style="text-align: center;">
<td><%=articleRow.get("id")%></td>
<td><%=articleRow.get("regDate")%></td>
<td><%=articleRow.get("title")%></td>
<td><%=articleRow.get("body")%></td>
<td><a href="doDelete?id=<%=articleRow.get("id")%>">del</a></td>
</tr>
<%
}
%>
</tbody>
</table>
<div>
<% if (currentPage > 1) { %>
<a href="?page=<%=currentPage - 1%>&pageSize=<%=currentPageSize%>">이전</a>
<% } %>
<span>Page <%=currentPage%> of <%=totalPages%></span>
<% if (currentPage < totalPages) { %>
<a href="?page=<%=currentPage + 1%>&pageSize=<%=currentPageSize%>">다음</a>
<% } %>
</div>
<!-- <ul> -->
<%-- <% --%>
<%--// for (Map<String, Object> articleRow : articleRows) {--%>
<%-- %> --%>
<%-- <li><a href="detail?id=<%=articleRow.get("id")%>"><%=articleRow.get("id")%>번, --%>
<%-- <%=articleRow.get("regDate")%>,<%=articleRow.get("title")%>,<%=articleRow.get("body")%></a></li> --%>
<%-- <% --%>
<%--// }--%>
<%-- %> --%>
<!-- </ul> -->
</body>
</html>
이렇게 수정했다.
보는 바와 같이 잘 구현되었다 다음과 이전으로도 잘 간다. 20개를 보고 싶으면 20을 클릭하면 이렇게 스무개를 보여준다.
그럼 아래의 Page의 개수도 창 개수에 맞게 줄어든다.
그런데 글이 많아질 경우 페이지도 많아질텐데 계속 다음과 이전만 누를 수는 없을 것 같다는 생각이 들어서 숫자로 클릭할 수 있게 변경하고 싶어졌다.
<div>
<% if (startPage > 1) { %>
<a href="?page=1&pageSize=<%=currentPageSize%>">1</a>
<% if (startPage > 2) { %>
<span>...</span>
<% } %>
<% } %>
<% for (int i = startPage; i <= endPage; i++) { %>
<% if (i == currentPage) { %>
<span><%=i%></span>
<% } else { %>
<a href="?page=<%=i%>&pageSize=<%=currentPageSize%>"><%=i%></a>
<% } %>
<% } %>
<% if (endPage < totalPages) { %>
<% if (endPage < totalPages - 1) { %>
<span>...</span>
<% } %>
<a href="?page=<%=totalPages%>&pageSize=<%=currentPageSize%>"><%=totalPages%></a>
<% } %>
</div>
<form method="get" action="">
<label for="gotoPage">페이지로 이동:</label>
<input type="number" id="gotoPage" name="page" min="1" max="<%=totalPages%>" value="<%=currentPage%>">
<input type="hidden" name="pageSize" value="<%=currentPageSize%>">
<button type="submit">이동</button>
</form>
html구조를 이렇게 바꾸었고 웹상에서는 이렇게 보인다.
페이지로 이동 텝에서 숫자를 입력하면 해당 페이지로 넘어간다.
다음시간부터는 write, modify를 할 것 같다.
'Coding History' 카테고리의 다른 글
국비 지원 IT(웹앱개발) 취업반 강의 45일차 2 (HTML, CSS, JS) (0) | 2024.08.07 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 45일차 1 (HTML, CSS, JS) (0) | 2024.08.07 |
국비 지원 IT(웹앱개발) 취업반 강의 44일차 1 (HTML, CSS, JS) (0) | 2024.08.06 |
카카오 페이증권 모작 완료. (0) | 2024.08.04 |
국비 지원 IT(웹앱개발) 취업반 강의 42일차 (HTML, CSS, JS) (0) | 2024.08.04 |