[Spring] 페이징

이다혜·2023년 11월 16일
0

Spring

목록 보기
7/27
post-thumbnail

데이터가 많아지면 모든 데이터가 한 페이지에 보여지는 문제가 있다.
이러한 이유로 페이징은 반드시 필요하다.

💻 대량의 테스트 데이터 만들기

테스트를 위해 대량의 테스트 데이터를 만든다.

SbbApplicationTest.java

@SpringBootTest
public class SbbApplicationTest {
    @Autowired
    private QuestionService questionService;

	@Test
    void testJpa() {
        for (int i = 1; i < = 300; i++) {
            String subject = String.format("테스트 데이터입니다:[%03d]", i);
            String content = "내용무";
            this.questionService.create(subject, content);
        }
    }
}


💻 페이징 구현

Jpa 관련 라이브러리에 페이징을 위한 패키지들이 들어있다.

QuestionRepository.java

public interface QuestionRepository extends 
		(... 생략 ...)
        Page<Question> findAll(Pageable pageable);
}

✅ Pageable 객체를 입력받아 Page<Question> 타입 객체를 리턴하는 findAll 메서드를 생성했다.

QuestionService.java

public Page<Question> getList(int page) {
        Pageable pageable = PageRequest.of(page, 10);
        return questionRepository.findAll(pageable);
    }

✅ getList 메서드를 페이지 번호를 입력받아서 해당 페이지의 질문 목록을 리턴하는 메서드로 변경했다.

  • Pageable
    : 페이징과 정렬에 사용되는 객체이다. 이를 통해 데이터베이스에서 특정 범위의 결과를 가져오고, 정렬할 수 있다.
  • PageRequest.of(page, 10)
    • page : 조회할 페이지 번호
    • 10 : 한 페이지에 보여줄 게시물의 갯수

QuestionController

  @GetMapping("/list")
    public String list(Model model, @RequestParam(value="page", defaultValue = "0") int page) {
        Page<Question> paging = questionService.getList(page);
        model.addAttribute("paging", paging);
        return "question_list";
    }

http://localhost:8080/question/list?page=0 처럼 GET 방식으로 요청된 URL에서 page 값을 가져오기 위해 @RequestParam을 매개변수에 추가했다.
✅ page가 전달되지 않으면 defaultValue 값인 0으로 설정된다.
✅ 모델에 paging이라는 Page<Question> 객체를 담아서 view로 전달한다.

Page객체의 속성

항목설명
isEmpty페이지 존재 여부 (게시물이 있으면 false, 없으면 true)
totalElements전체 게시물 개수
totalPages전체 페이지 개수
size페이지당 보여줄 게시물 개수
number현재 페이지 번호
hasPrevious이전 페이지 존재 여부
hasNext다음 페이지 존재 여부

💻 http://localhost:8080/question/list?page=0 실행 결과

이제 다음과 같이 한 페이지에 10개의 게시물을 볼 수 있다.


💻 페이지 이동 기능 구현

지금은 queryString으로 직접 페이지 번호를 전송해야 페이지를 이동할 수 있다.
이전, 다음 과 같은 버튼을 눌러서 페이지를 이동할 수 있도록 만들어보자.

question_list.html

    <!-- 페이징처리 시작 -->
  <div th:if="${!paging.isEmpty()}">
      <ul class="pagination justify-content-center">
          <li class="page-item" th:classappend="${!paging.hasPrevious} ? 'disabled'">
              <a class="page-link"
                  th:href="@{|?page=${paging.number-1}|}">
                  <span>이전</span>
              </a>
          </li>
          <li th:each="page: ${#numbers.sequence(0, paging.totalPages-1)}"
              th:classappend="${page == paging.number} ? 'active'" 
              class="page-item">
              <a th:text="${page}" class="page-link" th:href="@{|?page=${page}|}"></a>
          </li>
          <li class="page-item" th:classappend="${!paging.hasNext} ? 'disabled'">
              <a class="page-link" th:href="@{|?page=${paging.number+1}|}">
                  <span>다음</span>
              </a>
          </li>
      </ul>
  </div>
  <!-- 페이징처리 끝 -->
  • th:classappend="${!paging.hasPrevious} ? 'disabled'"
    : 이전 페이지가 없으면 이전 버튼 비활성화
  • th:classappend="${!paging.hasNext} ? 'disabled'"
    : 다음 페이지가 없으면 다음 버튼 비활성화
  • th:href="@{|?page=${paging.number-1}|}"
    : 이전 페이지 링크
  • th:href="@{|?page=${paging.number+1}|}"
    : 다음 페이지 링크
  • th:each="page: ${#numbers.sequence(0,paging.totalPages-1)}"
    : 페이지 번호 리스트 루프
    • #numbers.sequence(start, end)
      : start부터 end 까지의 루프를 만들어 낸다.
  • th:classappend="${page == paging.number} ? 'active'"
    : 현재 페이지 번호와 같으면 active 적용
  • th:if="${page >= paging.number-5 and page <= paging.number+5}"
    : 현재 페이지를 기준으로 좌우 5개만 보이도록 한다.

💻 http://localhost:8080/question/list?page=0 실행 결과

페이징 처리가 잘 되었고 현재 페이지인 8번 페이지가 활성화되어 보인다.


💻 작성일시 역순으로 조회하기

현재 질문 리스트는 등록한 순서로 데이터가 표시된다.
최근에 작성한 게시물이 먼저 보이도록 수정하자.

QuestionService.java

  public Page<Question> getList(int page) {
        List<Sort.Order> sorts = new ArrayList<>();
        sorts.add(Sort.Order.desc("createDate"));
        Pageable pageable = PageRequest.of(page, 10, Sort.by(sorts));
        return questionRepository.findAll(pageable);
    }
  • List<Sort.Order> sorts = new ArrayList<>();
    : 정렬 순서를 정의하기 위해 Sort.Order 객체를 담는 리스트 생성
  • Sort.Order.desc("createData")
    : Sort.Order 객체를 이용하여 createDate 필드를 기준으로 내림차순 정렬을 수행하도록 설정
  • Sort.by(sorts)
    : PageRequest.of()메서드의 세번째 파라미터로 정렬 정보를 나타낸다.

0개의 댓글