페이징 처리를 처음부터 다시 구현하려면, 전체 과정을 단계별로 설명하고 코드를 제공하겠습니다. 페이징 처리는 데이터베이스에서 대량의 데이터를 효율적으로 조회하고, 클라이언트에게 페이지별로 나누어 보여주기 위한 기술입니다. 이 과정은 데이터베이스 쿼리 작성, 서비스 계층, 컨트롤러, 그리고 프론트엔드에서의 처리를 포함합니다.
1. 데이터베이스 쿼리 작성
데이터베이스에서 페이징 처리를 위한 SQL 쿼리를 작성합니다. MariaDB에서는 LIMIT과 OFFSET을 사용하여 페이징을 처리합니다.
예제 SQL 쿼리
SELECT ri.image_path, ri.image_name, r.room_name, r.street_address, rp.rent_price, ro.room_option
FROM room r
INNER JOIN room_image ri ON r.id = ri.room_id
INNER JOIN room_option ro ON r.id = ro.room_id
INNER JOIN room_price rp ON r.id = rp.room_id
LIMIT ? OFFSET ?;
- LIMIT ?은 페이지 크기(한 페이지에 보여줄 데이터의 수)를 의미합니다.
- OFFSET ?은 데이터베이스에서 시작할 위치를 의미합니다.
2. DAO (Data Access Object) 클래스
DAO 클래스는 데이터베이스와 상호작용하며, 페이징 처리를 위한 메소드를 구현합니다.
RoomDao.java
package com.example.app.dao;
import com.example.app.model.RoomListItemDto;
import java.util.List;
public interface RoomDao {
List<RoomListItemDto> findAllRoomListItems(int offset, int pageSize);
int countRooms();
}
RoomDaoImpl.java
package com.example.app.dao;
import com.example.app.model.RoomListItemDto;
import com.example.app.util.JdbcUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class RoomDaoImpl implements RoomDao {
@Override
public List<RoomListItemDto> findAllRoomListItems(int offset, int pageSize) {
String sql = "SELECT ri.image_path, ri.image_name, r.room_name, r.street_address, rp.rent_price, ro.room_option " +
"FROM room r " +
"INNER JOIN room_image ri ON r.id = ri.room_id " +
"INNER JOIN room_option ro ON r.id = ro.room_id " +
"INNER JOIN room_price rp ON r.id = rp.room_id " +
"LIMIT ? OFFSET ?";
try (Connection con = JdbcUtil.getCon();
PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setInt(1, pageSize);
pstmt.setInt(2, offset);
try (ResultSet rs = pstmt.executeQuery()) {
List<RoomListItemDto> roomList = new ArrayList<>();
while (rs.next()) {
String imagePath = rs.getString("image_path");
String imageName = rs.getString("image_name");
String roomName = rs.getString("room_name");
String streetAddress = rs.getString("street_address");
int rentPrice = rs.getInt("rent_price");
String roomOption = rs.getString("room_option");
RoomListItemDto dto = new RoomListItemDto(imagePath, imageName, roomName, streetAddress, rentPrice, roomOption);
roomList.add(dto);
}
return roomList;
}
} catch (SQLException e) {
e.printStackTrace();
return new ArrayList<>();
}
}
@Override
public int countRooms() {
String sql = "SELECT COUNT(*) FROM room";
try (Connection con = JdbcUtil.getCon();
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getInt(1);
}
return 0;
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
}
3. 서비스 계층
서비스 계층에서 비즈니스 로직을 구현합니다. 데이터베이스에서 페이징된 데이터를 가져오고, 총 데이터 개수를 계산하여 페이지 정보를 제공합니다.
RoomService.java
package com.example.app.service;
import com.example.app.model.RoomListItemDto;
import java.util.List;
import java.util.Map;
public interface RoomService {
List<RoomListItemDto> getRoomList(int pageNum, int pageSize);
int getTotalRoomCount();
Map<String, Object> calculatePagination(int pageNum, int pageSize, int totalCount);
}
RoomServiceImpl.java
package com.example.app.service;
import com.example.app.dao.RoomDao;
import com.example.app.dao.RoomDaoImpl;
import com.example.app.model.RoomListItemDto;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RoomServiceImpl implements RoomService {
private RoomDao roomDao = new RoomDaoImpl();
@Override
public List<RoomListItemDto> getRoomList(int pageNum, int pageSize) {
int offset = (pageNum - 1) * pageSize;
return roomDao.findAllRoomListItems(offset, pageSize);
}
@Override
public int getTotalRoomCount() {
return roomDao.countRooms();
}
@Override
public Map<String, Object> calculatePagination(int pageNum, int pageSize, int totalCount) {
Map<String, Object> paginationInfo = new HashMap<>();
int pageCount = (int) Math.ceil((double) totalCount / pageSize);
int startPage = ((pageNum - 1) / 10) * 10 + 1;
int endPage = Math.min(startPage + 9, pageCount);
paginationInfo.put("pageCount", pageCount);
paginationInfo.put("startPage", startPage);
paginationInfo.put("endPage", endPage);
paginationInfo.put("pageNum", pageNum);
return paginationInfo;
}
}
4. 컨트롤러 (서블릿)
컨트롤러에서 사용자의 요청을 처리하고, 서비스 계층을 호출하여 결과를 JSP에 전달합니다.
RoomController.java
package com.example.app.controller;
import com.example.app.model.RoomListItemDto;
import com.example.app.service.RoomService;
import com.example.app.service.RoomServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@WebServlet("/roomList")
public class RoomController extends HttpServlet {
private RoomService roomService = new RoomServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int pageNum = Integer.parseInt(req.getParameter("pageNum"));
int pageSize = 10; // 한 페이지에 보여줄 항목 수
List<RoomListItemDto> roomList = roomService.getRoomList(pageNum, pageSize);
int totalRoomCount = roomService.getTotalRoomCount();
Map<String, Object> paginationInfo = roomService.calculatePagination(pageNum, pageSize, totalRoomCount);
req.setAttribute("list", roomList);
req.setAttribute("pageCount", paginationInfo.get("pageCount"));
req.setAttribute("startPage", paginationInfo.get("startPage"));
req.setAttribute("endPage", paginationInfo.get("endPage"));
req.setAttribute("pageNum", paginationInfo.get("pageNum"));
req.getRequestDispatcher("/WEB-INF/views/roomList.jsp").forward(req, resp);
}
}
5. JSP 페이지
JSP 페이지에서는 전달받은 데이터를 사용하여 페이지를 구성합니다. 기본적인 페이지 네비게이션을 구현합니다.
roomList.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>Room List</title>
</head>
<body>
<h1>Room List</h1>
<table border="1">
<tr>
<th>Image</th>
<th>Name</th>
<th>Address</th>
<th>Price</th>
<th>Option</th>
</tr>
<c:forEach var="room" items="${list}">
<tr>
<td><img src="${room.imagePath}" alt="${room.imageName}" width="100"/></td>
<td>${room.roomName}</td>
<td>${room.streetAddress}</td>
<td>${room.rentPrice}</td>
<td>${room.roomOption}</td>
</tr>
</c:forEach>
</table>
<div>
<c:forEach var="i" begin="${startPage}" end="${endPage}">
<a href="roomList?pageNum=${i}">${i}</a>
<c:if test="${i < endPage}">
</c:if>
</c:forEach>
</div>
</body>
</html>
'Java ☕️' 카테고리의 다른 글
IntelliJ IDEA에서 Gradle 빌드가 Java 17을 사용하도록 설정하는 방법 (0) | 2024.11.26 |
---|---|
cos.jar 설치 (0) | 2024.07.19 |
[Java/Maven] Eclipse에서 Maven Project 생성 후 배포 + jdbc driver mariadb 설정 (0) | 2024.07.10 |
Eclipse에서 만든 프로젝트 Apache-tomcat(아파치 톰캣)으로 자동 배포(deployment)하기 (0) | 2024.07.04 |
댓글 추가될수록 본게시글에도 숫자뜨도록 (0) | 2024.07.03 |
페이징 처리를 처음부터 다시 구현하려면, 전체 과정을 단계별로 설명하고 코드를 제공하겠습니다. 페이징 처리는 데이터베이스에서 대량의 데이터를 효율적으로 조회하고, 클라이언트에게 페이지별로 나누어 보여주기 위한 기술입니다. 이 과정은 데이터베이스 쿼리 작성, 서비스 계층, 컨트롤러, 그리고 프론트엔드에서의 처리를 포함합니다.
1. 데이터베이스 쿼리 작성
데이터베이스에서 페이징 처리를 위한 SQL 쿼리를 작성합니다. MariaDB에서는 LIMIT과 OFFSET을 사용하여 페이징을 처리합니다.
예제 SQL 쿼리
SELECT ri.image_path, ri.image_name, r.room_name, r.street_address, rp.rent_price, ro.room_option FROM room r INNER JOIN room_image ri ON r.id = ri.room_id INNER JOIN room_option ro ON r.id = ro.room_id INNER JOIN room_price rp ON r.id = rp.room_id LIMIT ? OFFSET ?;
- LIMIT ?은 페이지 크기(한 페이지에 보여줄 데이터의 수)를 의미합니다.
- OFFSET ?은 데이터베이스에서 시작할 위치를 의미합니다.
2. DAO (Data Access Object) 클래스
DAO 클래스는 데이터베이스와 상호작용하며, 페이징 처리를 위한 메소드를 구현합니다.
RoomDao.java
package com.example.app.dao; import com.example.app.model.RoomListItemDto; import java.util.List; public interface RoomDao { List<RoomListItemDto> findAllRoomListItems(int offset, int pageSize); int countRooms(); }
RoomDaoImpl.java
package com.example.app.dao; import com.example.app.model.RoomListItemDto; import com.example.app.util.JdbcUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; public class RoomDaoImpl implements RoomDao { @Override public List<RoomListItemDto> findAllRoomListItems(int offset, int pageSize) { String sql = "SELECT ri.image_path, ri.image_name, r.room_name, r.street_address, rp.rent_price, ro.room_option " + "FROM room r " + "INNER JOIN room_image ri ON r.id = ri.room_id " + "INNER JOIN room_option ro ON r.id = ro.room_id " + "INNER JOIN room_price rp ON r.id = rp.room_id " + "LIMIT ? OFFSET ?"; try (Connection con = JdbcUtil.getCon(); PreparedStatement pstmt = con.prepareStatement(sql)) { pstmt.setInt(1, pageSize); pstmt.setInt(2, offset); try (ResultSet rs = pstmt.executeQuery()) { List<RoomListItemDto> roomList = new ArrayList<>(); while (rs.next()) { String imagePath = rs.getString("image_path"); String imageName = rs.getString("image_name"); String roomName = rs.getString("room_name"); String streetAddress = rs.getString("street_address"); int rentPrice = rs.getInt("rent_price"); String roomOption = rs.getString("room_option"); RoomListItemDto dto = new RoomListItemDto(imagePath, imageName, roomName, streetAddress, rentPrice, roomOption); roomList.add(dto); } return roomList; } } catch (SQLException e) { e.printStackTrace(); return new ArrayList<>(); } } @Override public int countRooms() { String sql = "SELECT COUNT(*) FROM room"; try (Connection con = JdbcUtil.getCon(); PreparedStatement pstmt = con.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { return rs.getInt(1); } return 0; } catch (SQLException e) { e.printStackTrace(); return 0; } } }
3. 서비스 계층
서비스 계층에서 비즈니스 로직을 구현합니다. 데이터베이스에서 페이징된 데이터를 가져오고, 총 데이터 개수를 계산하여 페이지 정보를 제공합니다.
RoomService.java
package com.example.app.service; import com.example.app.model.RoomListItemDto; import java.util.List; import java.util.Map; public interface RoomService { List<RoomListItemDto> getRoomList(int pageNum, int pageSize); int getTotalRoomCount(); Map<String, Object> calculatePagination(int pageNum, int pageSize, int totalCount); }
RoomServiceImpl.java
package com.example.app.service; import com.example.app.dao.RoomDao; import com.example.app.dao.RoomDaoImpl; import com.example.app.model.RoomListItemDto; import java.util.HashMap; import java.util.List; import java.util.Map; public class RoomServiceImpl implements RoomService { private RoomDao roomDao = new RoomDaoImpl(); @Override public List<RoomListItemDto> getRoomList(int pageNum, int pageSize) { int offset = (pageNum - 1) * pageSize; return roomDao.findAllRoomListItems(offset, pageSize); } @Override public int getTotalRoomCount() { return roomDao.countRooms(); } @Override public Map<String, Object> calculatePagination(int pageNum, int pageSize, int totalCount) { Map<String, Object> paginationInfo = new HashMap<>(); int pageCount = (int) Math.ceil((double) totalCount / pageSize); int startPage = ((pageNum - 1) / 10) * 10 + 1; int endPage = Math.min(startPage + 9, pageCount); paginationInfo.put("pageCount", pageCount); paginationInfo.put("startPage", startPage); paginationInfo.put("endPage", endPage); paginationInfo.put("pageNum", pageNum); return paginationInfo; } }
4. 컨트롤러 (서블릿)
컨트롤러에서 사용자의 요청을 처리하고, 서비스 계층을 호출하여 결과를 JSP에 전달합니다.
RoomController.java
package com.example.app.controller; import com.example.app.model.RoomListItemDto; import com.example.app.service.RoomService; import com.example.app.service.RoomServiceImpl; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Map; @WebServlet("/roomList") public class RoomController extends HttpServlet { private RoomService roomService = new RoomServiceImpl(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int pageNum = Integer.parseInt(req.getParameter("pageNum")); int pageSize = 10; // 한 페이지에 보여줄 항목 수 List<RoomListItemDto> roomList = roomService.getRoomList(pageNum, pageSize); int totalRoomCount = roomService.getTotalRoomCount(); Map<String, Object> paginationInfo = roomService.calculatePagination(pageNum, pageSize, totalRoomCount); req.setAttribute("list", roomList); req.setAttribute("pageCount", paginationInfo.get("pageCount")); req.setAttribute("startPage", paginationInfo.get("startPage")); req.setAttribute("endPage", paginationInfo.get("endPage")); req.setAttribute("pageNum", paginationInfo.get("pageNum")); req.getRequestDispatcher("/WEB-INF/views/roomList.jsp").forward(req, resp); } }
5. JSP 페이지
JSP 페이지에서는 전달받은 데이터를 사용하여 페이지를 구성합니다. 기본적인 페이지 네비게이션을 구현합니다.
roomList.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <head> <title>Room List</title> </head> <body> <h1>Room List</h1> <table border="1"> <tr> <th>Image</th> <th>Name</th> <th>Address</th> <th>Price</th> <th>Option</th> </tr> <c:forEach var="room" items="${list}"> <tr> <td><img src="${room.imagePath}" alt="${room.imageName}" width="100"/></td> <td>${room.roomName}</td> <td>${room.streetAddress}</td> <td>${room.rentPrice}</td> <td>${room.roomOption}</td> </tr> </c:forEach> </table> <div> <c:forEach var="i" begin="${startPage}" end="${endPage}"> <a href="roomList?pageNum=${i}">${i}</a> <c:if test="${i < endPage}"> </c:if> </c:forEach> </div> </body> </html>
'Java ☕️' 카테고리의 다른 글
IntelliJ IDEA에서 Gradle 빌드가 Java 17을 사용하도록 설정하는 방법 (0) | 2024.11.26 |
---|---|
cos.jar 설치 (0) | 2024.07.19 |
[Java/Maven] Eclipse에서 Maven Project 생성 후 배포 + jdbc driver mariadb 설정 (0) | 2024.07.10 |
Eclipse에서 만든 프로젝트 Apache-tomcat(아파치 톰캣)으로 자동 배포(deployment)하기 (0) | 2024.07.04 |
댓글 추가될수록 본게시글에도 숫자뜨도록 (0) | 2024.07.03 |