
totalPosts(모든 글 개수), currentPage(현재 페이지 번호), postsPerPage(한 페이지당 표시할 글 개수), displayPageNum(한 번에 표시할 페이지 개수), totalPages(총 페이징 수), totalNum(총 개수)
prev(이전), next(다음), startPage, endPage
prev는 currentPage로 구한 startPage가 1인 경우 false고, 나머지 경우는 모두 true.
prev = (startPage == 1) ? false : true
next는 currentPage로 구한 endPage가 totalPages(모든 페이지 개수)인 경우 false고, 나머지 경우는 true
next = (endPage == totalPages) ? false : true
endPage는 currentPage, displayPageNum, totalPages 세 가지 값에 의존( endPage는 현재 페이지의 마지막 번호)
endPage = (( (currentPage - 1) / displayPageNum ) + 1 ) * displayPageNum
int endPage = (((currentPage-1)/displayPageNum)+1) * displayPageNum;
if(totalPages < endPage)
endPage = totalPages;
startPage도 endPage와 비슷한 원리
startPage = ((currentPage-1)/displayPageNum) displayPageNum + 1*
total page 개수는 total post 개수와 postsPerPage의 값에 의존
totalPages = ( (totalPosts - 1) / postsPerPage ) + 1 (이때, /는 '몫' 연산자임)
page를 파라미터로 받아와서 진행 -> 해당 파라미터가 null이 아니면 받아온 값으로 현재 페이지 번호 설정 (디폴트 값은 1)
String pageParam = request.getParameter("page");
int currentPage = 1;
if(pageParam!=null){
try{
currentPage = Integer.parseInt(pageParam);
}catch (NumberFormatException e){
currentPage = 1;
}
}
한 페이지당 몇개씩 보이게 할건지 설정
한번에 보이게 할 페이지 수 설정
값의 총 개수 -> DAO에서 해당 디비값의 전체 개수를 가져와서 사용
-controller
int total = dao.getRoomcountAll();
-DAO
//페이징 처리
//SQL 실행해서 offset부터 limit만큼 방 목록을 가져옴
public List<Room> getRoomsByPage(int offset, int limit) {
List<Room> rooms = new ArrayList<>();
String sql = "SELECT * FROM rooms ORDER BY id ASC LIMIT ?, ?";
try (
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)
) {
pstmt.setInt(1, offset);
pstmt.setInt(2, limit);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Room room = new Room();
room.setId(rs.getInt("id"));
room.setName(rs.getString("name"));
room.setStatus(rs.getString("status"));
rooms.add(room);
}
}
} catch (Exception e) {
System.err.println("페이징처리 실패: " + e.getMessage());
e.printStackTrace();
}
return rooms;
}
- backend -> java
1. DAO에서 원하는 페이지 만큼 값 가져오는 메소드 생성 :
-> DB 쿼리에서 페이징 처리 - SQL에서 LIMIT, OFFSET을 이용하여 원하는 "페이지만큼"만 가져오기 (SQL 실행해서 offset부터 limit만큼 글 개수 가져옴)
-DAO - 페이징 처리
public List<Room> getRoomsByPage(int offset, int limit) {
List<Room> rooms = new ArrayList<>();
String sql = "SELECT * FROM rooms ORDER BY id ASC LIMIT ?, ?";
try (
Connection conn = getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)
) {
pstmt.setInt(1, offset);
pstmt.setInt(2, limit);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
Room room = new Room();
room.setId(rs.getInt("id"));
room.setName(rs.getString("name"));
room.setStatus(rs.getString("status"));
rooms.add(room);
}
}
} catch (Exception e) {
System.err.println("페이징처리 실패: " + e.getMessage());
e.printStackTrace();
}
return rooms;
}
int postPage = 10; // 페이지당 방 수
int offset = (currentPage - 1) * postPage; // (3-1)*10 = 20
-paging
@Getter
@Setter
public class Paging {
private int currentpage; // 현재 페이지
private int pageNum; // 페이지 네비게이션 수
private boolean start; // 이전 버튼 필요 여부
private boolean end; // 다음 버튼 필요 여부
private int endPage; // 마지막 페이지 번호
private int startPage; // 시작 페이지 번호
private int totalPages; // 총 페이지 수
}
- controller
Paging paging = new Paging();
paging.setCurrentpage(currentPage);
paging.setPageNum(pageNum);
paging.setStart(prev);
paging.setEnd(next);
paging.setStartPage(startPage);
paging.setEndPage(endPage);
paging.setTotalPages(totalPages);
RoomDAO dao = new RoomDAO();
List<Room> dbRooms = dao.getRoomsByPage(offset, postPage);
List<Room> displayRooms = new ArrayList<>();
for (Room dbRoom : dbRooms) {
Room memoryRoom = findRoomById(dbRoom.getId());
if (memoryRoom != null) {
displayRooms.add(memoryRoom); // 메모리의 최신 상태 사용
} else {
dbRoom.setPlayers(new ArrayList<>());
displayRooms.add(dbRoom);
roomSet.add(dbRoom); // 메모리에 없는 방은 등록해줌
}
}
request.setAttribute("roomList", displayRooms);
- frontend
--> jsp로 구현
<!-- 페이지 네비게이션 -->
<c:if test="${paging.totalPages > 1}">
<div class="pagination">
<!-- 이전 페이지 링크 -->
<c:if test="${paging.currentpage > 1}">
<a href="lobby?page=${paging.currentpage - 1}" class="page-link">« 이전</a>
</c:if>
<!-- 페이지 번호 목록 -->
<c:forEach var="i" begin="${paging.startPage}" end="${paging.endPage}">
<c:choose>
<c:when test="${i == paging.currentpage}">
<span class="current">${i}</span>
</c:when>
<c:otherwise>
<a href="lobby?page=${i}">${i}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<!-- 다음 페이지 링크 -->
<c:if test="${paging.currentpage < paging.totalPages}">
<a href="lobby?page=${paging.currentpage + 1}" class="page-link">다음 »</a>
</c:if>
</div>
</c:if>
--> javascript로 이벤트
// 페이지 링크 클릭 이벤트 바인딩
function attachPaginationListeners() {
const pageLinks = document.querySelectorAll('.pagination-link');
pageLinks.forEach(link => {
link.addEventListener('click', function (event) {
event.preventDefault();
const page = parseInt(this.dataset.page);
if (!isNaN(page)) {
currentPage = page;
refreshRoomList(currentPage);
}
});
});
}