Adventure Time - Finn 3
본문 바로가기
카테고리 없음

페이지네이션

by hyun9_9 2024. 4. 13.

페이지네이션은 크게 2가지로 나뉜다

1. 프론트엔드에서 모든 데이터를 받아와 페이징하는 방법

2. 모델로부터 데이터를 페이지에 맞게 가져오는 방법

2가지가 있다

 

나는 2번 방법으로 제작해 보았다

먼저 페이징 처리를 하기 위해선

	// 쪽지 목록 (회원)
	private static final String SELECTALL_LETTER_LIST = "SELECT LETTER_ID, SENDER, TITLE, LETTER_CONTENTS, LETTER_DATE, "
			+ "LETTER_STATUS FROM LETTER WHERE LOGIN_ID=? ORDER BY LETTER_DATE DESC LIMIT ?, ?";

LIMIT를 사용해야합니다

LIMIT 은 범위를 지정할수 있는 함수로서

첫 번째 매개변수는 반환할 행의 시작 위치

두 번째 매개변수는 반환할 최대 수를 지정합니다

 

그럼 범위를 지정할수 있는 SQL이 있으므로

행의 시작위치를 구하는 메서드를 제작하게 됩니다

 

	// 페이지 번호에 따른 offset 계산
	public int calculateOffset(PageInfoDTO pDTO) {
		//(현재 페이지 -1) * 몇개씩 자를 건지 
		//ex) (1 -1)*10 = 0 - 0~9
		//(2-1)*10 = 10 - 10~19 
		pDTO.setOffset((pDTO.getCurrentPage() - 1) * pDTO.getPasingnationSize());
		return pDTO.getOffset();
	}

 

그럼 이제 컨트롤러를 제작해보면

 

package com.jarvis.BalanceGame.controller.user.page;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;
import com.jarvis.BalanceGame.model.dto.LetterDTO;
import com.jarvis.BalanceGame.model.dto.PageInfoDTO;
import com.jarvis.BalanceGame.model.dto.QuestionDTO;
import com.jarvis.BalanceGame.service.LetterService;
import com.jarvis.BalanceGame.service.PageInfoService;

import jakarta.servlet.http.HttpSession;
import kotlinx.serialization.json.Json;

@Controller
@RequestMapping("/user")
public class LetterListPageController {

	@Autowired
	private LetterService letterService;
	
	@Autowired
	private PageInfoService pageInfoService;
	
	
	@GetMapping("/letterListPage")
	public String letterListPageController(LetterDTO lDTO, PageInfoDTO pDTO, Model model, HttpSession session, Gson gson) {
		// 페이징 처리 해야한다
		// 뷰에서 데이터를 받는다 몇페이지 클릭하는지 데이터 받음
		// 그걸 모델에 보내준다
		String loginId = (String)session.getAttribute("loginId");
		if(pDTO.getCurrentPage() == 0) {
			//처음 진입 시 어떤 페이지인지 모르기 때문에
			//현재 페이지를 1로 설정
			System.out.println(">>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<");
			pDTO.setCurrentPage(1);
		}
		
		//해당 유저의 우편을 가져오기위해 설정
		pDTO.setLoginId(loginId);
		//10개씩 우편을 가져오기 위해 10으로 설정
		pDTO.setPasingnationSize(10);
		
		//몇번째의 데이터를 가져올지 설정
		//ex) 1페이지면 0~9 - offset 0
		// 2페이지면 10~19 - offset 10
		pDTO.setOffset(pageInfoService.calculateOffset(pDTO));
		System.out.println(pDTO.getOffset());
		//서치 컨디션으로 어떤 데이터를 가져올 것인지 설정
		pDTO.setSearchCondition("viewAllMessage");
		System.out.println("pDTO" + pDTO);
		//10개 씩 끊어서 데이터를 가져옴
		List<PageInfoDTO> datas = pageInfoService.selectAll(pDTO);
		
		
		//총패이지 수를 가져오기 위해 메세지 총 개수 를 가져옴
		lDTO.setSearchCondition("messageCntMember");
		lDTO = letterService.selectOne(lDTO);
		System.out.println(lDTO);
		//가져온 우편 개수
		pDTO.setTotalRows(lDTO.getCnt());
		int totalPage = pageInfoService.calcTotalPages(pDTO);	// 총페이지 수
		

		System.out.println(totalPage);
		
		if(datas != null) {
			model.addAttribute("letterDatas", datas);
			model.addAttribute("totalPage", totalPage);
			model.addAttribute("page", pDTO.getCurrentPage());
		}else {
			model.addAttribute("status", "fail");
			model.addAttribute("msg", "등록된 문제가 없습니다.");
			model.addAttribute("redirect", "");
			return "alert";
		}
		
		return "/user/letterList";

	}
}

 

위에서 총 페이지 개수를 프론트 쪽으로 반환해주는데 이 부분은

	// 토탈 페이지 계산
	public int calcTotalPages(PageInfoDTO pDTO) {
		if (pDTO.getTotalRows() <= 0) { // 데이터가 없다면
			pDTO.setTotalPages(0); // 토탈페이지는 0
		}
		pDTO.setTotalPages(pDTO.getTotalRows() / pDTO.getPasingnationSize()); // 토탈 페이지 개수
		if (pDTO.getTotalRows()>10 && pDTO.getTotalRows() % pDTO.getPasingnationSize() > 0) { // 토탈 페이지 계산했을 때 나머지가 0보다 크다면
			pDTO.setTotalPages(pDTO.getTotalPages() + 1); // 페이지 개수 1 증가
		}
		return pDTO.getTotalPages();
	}

이 메서드를 사용해서 총 페이지 개수 또한 받아옵니다

 


	// 페이지 번호 노출 범위 설정 (5개씩)
	var paginationRange = 5;

	// 페이지 번호 목록 생성 함수
	function generatePagination() {
	    var paginationHTML = '<nav class="blog-pagination justify-content-center d-flex"><ul class="pagination">';

	    // 이전 페이지 링크 추가
	    paginationHTML += '<li class="page-item"><a onclick="beforeData();" class="page-link" aria-label="Previous"><i class="ti-angle-left"></i></a></li>';

	 // 페이지 번호 목록 추가
	    for (var i = Math.max(1, Math.min(currentPage - Math.floor(paginationRange / 2), totalPage - paginationRange + 1)); i <= Math.min(totalPage, Math.max(currentPage + Math.floor(paginationRange / 2), paginationRange)); i++) {
	        if (i === currentPage) {
	            paginationHTML += '<li class="page-item active"><a onclick="'+pageName+'('+i+')"'+ ' class="page-link">' + i + '</a></li>';
	        } else {
	            paginationHTML += '<li class="page-item"><a onclick="'+pageName+'('+i+')"'+ 'class="page-link">' + i + '</a></li>';
	        }
	    }

	    // 다음 페이지 링크 추가
	    paginationHTML += '<li class="page-item"><a onclick="nextData();" class="page-link" aria-label="Next"><i class="ti-angle-right"></i></a></li>';

	    paginationHTML += '</ul></nav>';

	    return paginationHTML;
	}

	// 페이지 목록 업데이트 함수
	function updatePagination() {
	    var paginationContainer = document.querySelector('.blog-pagination');
	    if (paginationContainer) {
	        paginationContainer.innerHTML = generatePagination();
	    }
	}
	function nextData() {
		var commentBox = document.getElementById('comments-area');
            if (commentBox) {
                // comment-box로 이동
                commentBox.scrollIntoView({ behavior: 'smooth' });
            }
	    if ((currentPage + 1) <= totalPage) {
			currentPage=currentPage+1;
	       commentAll();
	    }
	}

	function beforeData() {
		var commentBox = document.getElementById('comments-area');
            if (commentBox) {
                // comment-box로 이동
                commentBox.scrollIntoView({ behavior: 'smooth' });
            }
	    if ((currentPage - 1) >= 1) {
			currentPage=currentPage-1;
	        commentAll();
	    }
	}
	
	
	function commentPage(id){
	console.log("다음 번호 클릭");
	currentPage = id;
	console.log("해당 번호"+currentPage);
	var commentBox = document.getElementById('comments-area');
    if (commentBox) {
        // comment-box로 이동
        commentBox.scrollIntoView({ behavior: 'smooth' });
    }
	
	commentAll();
}

위 페이징 번호를 생성하는 js를 통해 페이징 처리를 성공적으로 할 수 있습니다