Paging 처리

박세건·2023년 3월 26일
0

페이징처리가 쉽게 이해되지않아서 작성했다
page처리한 목록을 보는 url 주소를 /paging 이라고했을때

@GetMapping("/paging")
    public String paging(@PageableDefault(page = 1) Pageable pageable, Model model) {

        Page<MemberDTO> memberDTOPage=memberService.paging(pageable);
        int blockLimit=3;   //화면에서 보여줄 page 묶음의 개수
        //pageable.getNumberOfPages 는 현재 페이지를 의미
        int startPage = (((int) Math.ceil((double) pageable.getPageNumber() / blockLimit) / blockLimit) - 1) * blockLimit + 1;
        int endPage = (startPage + blockLimit - 1) < memberDTOPage.getTotalPages() ? startPage + blockLimit - 1 : memberDTOPage.getTotalPages();
        model.addAttribute("memberList",memberDTOPage);
        model.addAttribute("startPage",startPage);
        model.addAttribute("endPage",endPage);
        return "paging";
    }

@PageableDefault(page = 1)의 의미는 기본적인 주소는 /paging?page=숫자 이런식으로 들어와야하지만
/paging 만 입력해도 /paging/page=1 을 기본설정으로 하는것이다.

public Page<MemberDTO> paging(Pageable pageable) {
        //페이지는 0부터 시작하기때문에
        int page = pageable.getPageNumber() - 1;
        int pageLimit=3; //한페이지에 보여줄 회원 수
        //한페이지당 3명의 회원을 보여주고 정렬 기준은 id기준으로 올므차순 정렬
        //page 위치에 있는 값은 0 부터 시작
        Page<MemberEntity> memberEntityPage = memberRepository.findAll(PageRequest.of(page, pageLimit, Sort.by(Sort.Direction.ASC, "memberId")));

        Page<MemberDTO> memberDTOPage = memberEntityPage.map(memberEntity ->
                new MemberDTO(memberEntity.getMemberId(), memberEntity.getMemberEmail(), memberEntity.getMemberPassword(), memberEntity.getMemberName(),
                        memberEntity.getMemberAge(), memberEntity.getMemberPhone()));
        return memberDTOPage;
    }

Pageable 객체를 갖고 Page 를 리턴시켜야한다
기본적인 흐름은 현재의 페이지(page)와 한 페이지에서 보여줄 회원 수(pageLimit)과 정렬 기준이 필요하다
page와 pageLimit이 정해졌다면
memberRepository에서 Page<> 객체로 가져오기위해 findAll함수를 사용한다 이때 속성값으로
PageRequest.of()함수를 사용한다
PageRequest.of() 의 매개변수로 들어가는 값이 바로
page, pageLimit, 정렬 값 이다

Page<MemberEntity> memberEntityPage = memberRepository.findAll(PageRequest.of(page, pageLimit, Sort.by(Sort.Direction.ASC, "memberId")));

정렬기준은 ASC(오름차순), DES(내림차순) 이 있고 그 뒤에 정렬기준이 되는 필드 값을 넣어준다.
Page 객체를 가져왔으면 이 객체를 DTO 객체로 변환시켜줘야한다
List<> 형을 사용해서 DTO 객체로 변경시켜줄 수 있지만 Page<> 에 담긴 좋은 함수들을 편리하게 사용하기위해 Page 속성의 map() 함수를 사용해서 DTO 객체에 매핑시킨다
기본형식

Page<MemberDTO> memberDTOPage = memberEntityPage.map(memberEntity ->
              new MemberDTO(memberEntity.getMemberId(), memberEntity.getMemberEmail(), memberEntity.getMemberPassword(), memberEntity.getMemberName(),
                      memberEntity.getMemberAge(), memberEntity.getMemberPhone()));

다시 Controller로 돌아와서 이제 Page<>객체와 startPage, endPage, blockLimit이 정해졌기때문에 이 값들을 html로 보내준다

  <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>paging</title>
</head>
<body>
<table>
  <tr>
    <th>이메일&nbsp;</th>
    <th>&nbsp;이름</th>
  </tr>
  <tr th:each="member: ${memberList}">
    <td><a th:href="@{|/member/${member.memberId}|}" th:text="${member.memberEmail}"></a></td>
    <td th:text="${member.memberName}"></td>
  </tr>
</table>
<!--첫번째 페이지로 이동-->
<a href="/member/paging?page=1">처음</a>
</body>
<!--이전 페이지로 이동-->
<a th:href="${memberList.first}?'#':@{|/member/paging?page=${memberList.number}|}">이전</a>

<span th:each="page:${#numbers.sequence(startPage,endPage)}">
  <!--현재 페이지는 링크가 아닌 숫자로만-->
  <span th:if="${page==memberList.number+1}" th:text="${page}"></span>

  <!--현재 페이지가 아니라면 링크로 설정-->

  <span th:unless="${page==memberList.number+1}">
    <a th:href="@{|/member/paging?page=${page}|}" th:text="${page}"></a>
  </span>
</span>

<!--다음 페이지로 이동-->
<a th:href="${memberList.last}?'#':@{|/member/paging?page=${memberList.number+2}|}">다음</a>
<!--마지막 페이지로 이동-->
<a th:href="@{|/member/paging?page=${memberList.totalPages}|}">마지막</a>
</html>
![](https://velog.velcdn.com/images/parksegun/post/59748847-cf1e-42e2-9eff-32f50dedc75a/image.png)

참고!!
page는 0부터 시작한다는것!
page 속성으로 number, first, last, totoalpages 가능!
first와 last는 boolean 타입이다!

profile
멋있는 사람 - 일단 하자

0개의 댓글