페이징처리가 쉽게 이해되지않아서 작성했다
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>이메일 </th>
<th> 이름</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>

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