국비 지원 IT(웹앱개발) 취업반 강의 44일차 2 (HTML, CSS, JS)

BlackBird·2024년 8월 7일

개발자 취업 일지

목록 보기
73/116

페이지를 글 목록 수에 따라서 나누려고 한다.

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를 할 것 같다.

profile
한영신의 벨로그입니다.

0개의 댓글