본문 바로가기
JAVA/JPA

Java Spring JPA 검색을 포함한 페이지네이션 pagenation 기능 구현

by hhana 2023. 4. 27.
프로젝트명 : 3rdAssignment
사용언어 및 프레임워크 : Java8, JQuery, Thymeleaf, JPA, Gradle ...

 

<result.html>

<!-- 페이징정보 시작-->
<div class="paging flex center">
    <ol class="flex">
        <!-- 첫 페이지로 -->
        <li>
            <a th:href="|/result?pageNum=1&search=${search}&searchType=${searchType}|">&lt;&lt;</a>
        </li>
        <!-- Prev Sign -->
        <li th:if="${pi.pageStart ne 1}"> <!-- ne(!=) -->
            <a th:href="|/result?pageNum=${pi.pageStart - 1}&search=${search}&searchType=${searchType}|">&lt;</a>
        </li>
    </ol>
    <ol class="page-list flex">
        <!-- pageStart ~ pageEnd 반복 -->
        <li th:each="pageNo:${#numbers.sequence(pi.pageStart,pi.pageEnd)}">
            <a th:href="|/result?pageNum=${pageNo}&search=${search}&searchType=${searchType}|" th:class="${pageNo == rent.getNumber()+1 ? 'select' : ''}">[[${pageNo}]]</a>
        </li>
    </ol>
    <ol class="flex">
        <!-- Next Sign -->
        <li th:if="${pi.pageEnd < pi.pageTotal}">
            <a th:href="|/result?pageNum=${pi.pageEnd + 1}&search=${search}&searchType=${searchType}|">&gt;</a>
        </li>
        <!-- 마지막 페이지로 -->
        <li>
            <a th:href="|/result?pageNum=${pi.pageTotal}&search=${search}&searchType=${searchType}|">&gt;&gt;</a>
        </li>
    </ol>
    <input type="hidden" id="p-length" th:value="${pi.pLength}">
</div>
<!-- 페이징정보 마지막-->
<!-- 페이징 다른 버전
<div class="flex center">
    <div class="pageBTN" th:if="${rent.getTotalPages}>0">
        <a th:if="${rent.hasPrevious()}"
        th:href="|/result?pageNum=${rent.getNumber()}&search=${search}&searchType=${searchType}|">[이전]</a>
        <a th:if="${rent.getNumber()-1}>0" th:text="${rent.getNumber()-1}"
        th:href="|/result?pageNum=${rent.getNumber()-1}&search=${search}&searchType=${searchType}|">현재페이지-2</a>
        <a th:if="${rent.getNumber()}>0" th:text="${rent.getNumber()}"
        th:href="|/result?pageNum=${rent.getNumber()}&search=${search}&searchType=${searchType}|">현재페이지-1</a>
        <a id="currentPage" th:text="${rent.getNumber()+1}">현재페이지</a>
        <a th:if="${rent.getNumber()+2<=rent.getTotalPages()}" th:text="${rent.getNumber()+2}"
        th:href="|/result?pageNum=${rent.getNumber()+2}&search=${search}&searchType=${searchType}|">현재페이지+1</a>
        <a th:if="${rent.getNumber()+3<=rent.getTotalPages()}" th:text="${rent.getNumber()+3}"
        th:href="|/result?pageNum=${rent.getNumber()+3}&search=${search}&searchType=${searchType}|">현재페이지+2</a>
        <a th:if="${rent.hasNext()}"
        th:href="|/result?pageNum=${rent.getNumber()+2}&search=${search}&searchType=${searchType}|">[다음]</a>
    </div>
</div>
-->

 

<RentServiceProcess.java>

// 최적의 임대료 찾기
@Override
public void findBestRent(int pageNum, String search, String searchType, Model model) {

    // 리스트 페이지에 출력해줄 데이터리스트
    Page<RentEntity> rent = null;

    // 페이징기능(페이지인덱스번호,페이지 사이즈,정렬방식,정렬할 컬럼이름)
    Pageable page = PageRequest.of(pageNum - 1, pageSize, Direction.DESC, "rentNo");

    int rowTotal = 0;

    if (search.equals("전체")) {
        // 만약 검색한 내용이 없다면 전체 리스트 정보 가져오기
        rent = rentRepository.findAll(page); // 전체 데이터를 넘기면 안돼요 페이지에 해당하는 게시글만 가져와야함
        rowTotal = (int) rentRepository.count();
    } else {
        if (searchType.equals("name")) {
            // 만약 검색한 내용이 이름을 검색한 것이라면 해당 리스트를 가져오기
            rent = rentRepository.findByRegUserContaining(search, page);
            rowTotal = (int) rent.getTotalElements();
        } else if (searchType.equals("roomCnt")) {
            // 만약 검색한 내용이 보유원룸수를 검색한 것이라면 해당 리스트를 가져오기
            int roomCnt = Integer.parseInt(search);
            rent = rentRepository.findByRoomCntBetween(roomCnt, roomCnt, page);
            rowTotal = (int) rent.getTotalElements();
        }
    }

    // 페이지정보
    PageDTO pageInfo = PageDTO.getInstance(pageNum, rowTotal, pageSize, 5);

    model.addAttribute("searchType", searchType);
    model.addAttribute("search", search);
    model.addAttribute("rent", rent.map(RentDetailDTO::new));
    model.addAttribute("pi", pageInfo);
}

 

<PageDTO>

@Getter
public class PageDTO {
	private int pageTotal;
	private int pageStart;
	private int pageEnd;
	private int pLength;

	/**
	 * @param page     현재 페이지번호
	 * @param rowTotal 총 게시글 수
	 * @param limit    한 페이지에 보여지는 게시글 수
	 * @param pLength  보여지는 페이지 번호 개수 숫자로 입력
	 */
	public static PageDTO getInstance(int page, int rowTotal, int limit, int pLength) {
		return new PageDTO(page, rowTotal, limit, pLength);
	}

	/////////////// 생성자///////////////
	/**
	 * 먼저 인스턴스 변수 pLength에 pLength 값을 할당합니다.
	 * 그런 다음 총 행 수(rowTotal)를 페이지당 표시할 행 수(limit)로 나누어 총 페이지 수를 계산합니다.
	 * 나머지 페이지가 있는 경우, 전체 페이지 수가 1씩 증가합니다.
	 * 
	 * 다음으로 현재 페이지 번호(page)를 표시할 페이지 번호(pLength)로 나누어 페이지 그룹(pGroup)을 계산합니다.
	 * 나머지가 있으면 페이지 그룹이 1씩 증가합니다.
	 * 
	 * 그런 다음 페이지 그룹에 표시할 페이지 번호를 곱하여 끝 페이지 번호(pageEnd)를 계산합니다.
	 * 시작 페이지 번호(pageStart)는 종료 페이지 번호에서 표시할 페이지 번호를 뺀 후 1을 추가하여 계산합니다.
	 * 
	 * 마지막으로, 끝 페이지 번호가 총 페이지 수보다 큰 경우, 끝 페이지 번호를 총 페이지 수보다 동일하게 설정합니다.
	 */
	private PageDTO(int page, int rowTotal, int limit, int pLength) {
		
		this.pLength = pLength;
		System.out.println(" >>>>> pLength : " + pLength);

		pageTotal = rowTotal / limit; // 총페이지 수 // Math.ceil(rowTotal / limit)
		
		if (rowTotal % limit != 0) {
			pageTotal++;
		}
		
		System.out.println(" >>>>> pageTotal : " + pageTotal);
		
		int pGroup = page / pLength;
		
		if (page % pLength != 0) {
			pGroup++; // % 나머지계산
		}
		
		pageEnd = pGroup * pLength;
		pageStart = pageEnd - pLength + 1;
		System.out.println(" >>>>> pageStart : " + pageStart);
		System.out.println(" >>>>> pageEnd : " + pageEnd);

		// 혹시 마지막 페이지 번호는? 총 페이지 수 보다 클 수 없어요
		if (pageEnd > pageTotal) {
			pageEnd = pageTotal;
		}
		
	}
}

 

 

'JAVA > JPA' 카테고리의 다른 글

JPA 검색 기능에 대하여! findBy, Containing, Between  (0) 2023.04.26

댓글