Spring

Springboot(JPA)-Page 구현

jaewoo 2022. 8. 21. 00:31

1.Controller

컨트롤러에서는 파라미터로 @PageableDefault 애노테이션으로 간단하게 page(보여줄 페이지), size(몇개인지), sort(정렬기준),direction(내림차순,오름차순) 을 받을 수 있다. 

이렇게 하지 않고 따로 page와 size를 받아 구현할 수 있지만 그러면 따로 Pageable에 구현체인 PageRequest.of를 사용해서 따로 구현해야한다. 그러기 보다는 파라미터로 바로 받는게 편한 것 같다.

값을 넘겨줄때는 이런 방식으로 줄 수도 있지만 이렇게 쿼리스트링으로 값을 주지 않는것이 일반적이고 이런 경우 @PagealbeDefault에 설정한 값이 자동으로 들어간다. 하지만 page에 값은 파라미터로 넘겨줘야한다 (page를 제외한 값들은 모두 위에 설정한 기본 값이 들어간 Pageable 객체가 만들어진다.)

이 컨트롤러를 통해 이 값을 View에 넘겨줄 것이다. 여기서 getPageNumber()는 현재 페이지 즉 파라미터로 넘겨준 page 값이다. page로 0을 넘겨준다면 첫번째 페이지가 보일것이다. getTotalPages()는 이름 그대로 전체 페이지이다. DB에 데이터가 40개가 있다면 우리는 컨트롤러에서 size를 5로 했기 때문에 getTotalPages값은 8이 나올 것이다.

 

2. Service

서비스 로직에 구현한 getPageination 메소드이다. 이 메소드를 통해 현재페이지를 getPageNumber()를 통해 넘겨 받는다. 

Math.max() 메소드는 두개의 값중 더 큰 값을 선택해서 대입해준다. PAGE_LENGTH는 화면에서 보여줄 페이지 개수이다. 

이런식으로 5개를 보여줄 것이기에 5를 넣었다. 화면에 보여주고 싶은 숫자를 넣어주면 된다. 여기서 우리가 컨트롤러에 만약 page=3 을 넘겨준다 생각하자 (page는 0부터 시작 우리가 보는 숫자는 1부터 봐야하기에 1을 더했다고 보면 편함)

그러면 getPageNumber는 당연히 3이다. 그럼 getPagination 에서 받는 currentPageNumber는 3이 들어온다. 

Math.max(1,0) 이 되고 여기서 큰 값인 1이 선택된다. 

 

-근데 이미지에서는 맨 좌측이 2이지 않은가?

이런 생각을 할 수 있다. 위에서 말한 것처럼 page는 0부터 시작이다. 그래서 View에서는 보여주는 값에 1을 다 더했다. 

계산되어 넘어가는 값은 즉 1,2,3,4,5가 넘어간다. 근데 View에서 1씩 다 더했기 때문에 2,3,4,5,6 이 나오는 것이다.

-왜 비교값을 0을 넣었나?

마이너스인 값이 넘어올 수도 있어서이다. 만약 두 값을 비교했을때 -1이 더 큰 값이라 startNumber에 대입된다면 우리가 보는 View에서는 0부터 시작된다. 

 

여기까지 이해했다면 Math.min()은 이해를 바로할 수 있다. 두개에 값중 작은 값을 선택한다. startNumber는 1이다(왜 1인지 모르면 위에 글을 다시보면 된다.) 

startNumber+PAGE_LENGTH는  6이다. 그럼 결국 startNumber는 1 그리고 endNumber는 6이된다. 여기서 문제가 있다.

 

-왜 1부터 6가지 넘기는 거지 다섯개면 1부터 5까지라고 생각할 수 있다,

이말도 맞는 말이다. 근데 중요한게 IntStream.range를 사용하여 boxed() 를 사용하여 Stream으로 바꾸고 List형태로 바꿔서 리턴한다. 여기서 range로 6미만 값까지 들어간다. 로그로 확인하면

3페이지 뷰에서는 1씩 모두 더했기에 4페이지를 클릭시 이 값이 넘어가는 것이다.

 

3. View

View에서 보면 th:each를 통해 반복문을 돌린다. pagination을 model에 담은 값은

이 값이다 결국 컨트롤러에 page값을 바꿀때마다 보여주는 페이지는 다섯개만 보여지고 거기서 현재 페이지는 가운대로 오게 된다. 계속해서 우리가 뷰에서 보는 페이지가 4페이지라고 해보자

그러면 [1,2,3,4,5] 가 넘어온다. 이 값을 pageNumber에 1씩 더한 걸 볼 수 있다. 그래서 우리가 보는 페이지는 결국

이렇게 된다. 

 

참고

https://fastcampus.co.kr/dev_online_befinal