Spring Data JPA #4 단순 게시글 처리 #2 쿼리 메서드의 페이징 처리와 정렬

2021. 10. 6. 15:27JAVA/Spring

이전 글

https://yonghwankim-dev.tistory.com/134

 

Spring Data JPA #4 단순 게시글 처리 #1 쿼리 메서드 사용

본 글은 스타트 스프링 부트 도서의 내용을 복습하기 위해 작성된 글입니다. 개요 Spring Data JPA의 CrudRepository만을 이용해서 create, read, update, delete 작업이 가능하나, 이는 너무 단순 작업입니다. 실

yonghwankim-dev.tistory.com

 

본 글은 스타트 스프링 부트 도서의 내용을 복습하기 위해 작성된 글입니다.

 

개요

본 글에서는 쿼리 메소드가 사용하는 페이징 처리와 정렬에 대해서 알아보고 Page<T> 타입을 사용하는 것을 알아봅니다.

  • 쿼리 메소드라는 메소드의 이름만으로 원하는 SQL을 실행하는 방법
  • @Query를 이용한 좀 더 구체화된 JPQL 처리
  • 페이징과 정렬에 대한 처리 (현재)
  • Querydsl을 이용한 동적 쿼리

 

1. 페이징 처리와 정렬

쿼리 메소드들에는 특이하게도 모든 쿼리 메소드의 마지막 파라미터로 페이지 처리를 할 수 있는 Pageable 인터페이스와 정렬을 처리하는 Sort 인터페이스를 사용할 수 있습니다.

 

Pageable 인터페이스는 무엇인가?

Pageable 인터페이스는 페이징 처리에 필요한 정보를 제공합니다. 보통 가장 많이 사용하는 것은 org.springframework.data.domain.Pageable 인터페이스를 구현한 클래스 중에 PageRequest 클래스를 이용하는 것입니다. (스프링 부트 2.0 이후의 경우 PageRequest.of()를 사용해야 합니다.)

 

org.zerock.persistence.BoardRepository 기본적인 페이징 처리

public interface BoardRepository extends CrudRepository<Board, Long>{

	// 게시물의 번호가 특정 숫자 이상인 게시물을 게시물 번호를 기준으로 내림차순으로 검색
	// 페이징 처리 
	// bno > ? ORDER BY bno DESC limit ?, ?
	public List<Board> findByBnoGreaterThanOrderByBnoDesc(Long bno, Pageable paging);
}

이전 글의 메소드와 동일하지만 다른 부분은 파라미터에 Pageable 인터페이스가 추가된 점이고 리턴타입으로 Collection<T> 대신 List<T>를 적용한 것이 달라졌습니다. Pageable 인터페이스가 적용되는 경우 리턴 타입은 Slice 타입, Page 타입, List 타입을 이용해야 합니다.

 

org.zerock.Boot03ApplicationTests 일부

	@Test
	void testBnoOrderByPaging() {
		// 게시물의 번호가 90보다 큰 게시물들을 게시물 번호를 기준으로 내림차순으로 검색
		// param1 : 페이지번호(0부터 시작)
		// param2 : 페이지당 데이터 수
		Pageable paging = PageRequest.of(0, 10);
				
		Collection<Board> results = repo.findByBnoGreaterThanOrderByBnoDesc(90L, paging);
				
		results.forEach(board->System.out.println(board));
	}

 

PageRequest 생성자

생성자 설명
PageRequest(int page, int size) 페이지 번호(0부터 시작), 페이지당 데이터 수
PageRequest(int page, int size, Sort.Direction direction, String... props) 페이지 번호, 페이지당 데이터 수, 정렬 방향, 속성(칼럼)들
PageRequest(int page, int size, Sort sort) 페이지 번호, 페이지당 데이터 수, 정렬 방향

Sort 클래스를 활용하여 OrderBy 키워드를 대체하여 원하는 방향을 파라미터로 결정할 수 있습니다.

 

아래 예제는 이전과 유사하지만 정렬 부분을 지정하지 않은 메소드를 추가합니다.

 

org.zerock.persistence.BoardRepository 인터페이스에 페이징, 정렬 처리

public interface BoardRepository extends CrudRepository<Board, Long>{

	// 게시물의 번호가 특정 숫자 이상인 게시물을 검색
	// order by절을 생략하고 정렬과 페이징 관련 부분을 Pageable 인터페이스가 처리 가능
	public List<Board> findByBnoGreaterThan(Long bno, Pageable paging);

}

쿼리 메서드에서 OrderBy 부분 없이 Pageable만을 파라미터로 처리하고 싶습니다. 메소드의 이름에서 정렬과 관련된 조건이 빠진 것은 PageRequest()를 이용해서 다음과 같이 처리할 수 있습니다.

 

org.zerock.Boot03ApplicationTests 일부

	@Test
	void testBnoPagingSort() {
		// 게시물의 번호가 0보다 큰 게시물들을 검색
		// 한 페이지에 10건의 게시물 페이징 처리
		// 페이징 처리된 결과에서 게시물 번호를 기준으로 오름차순 정렬 처리
		
		Pageable paging = PageRequest.of(0, 10,Sort.Direction.ASC,"bno");
		
		Collection<Board> results = repo.findByBnoGreaterThan(0L, paging);
		
		results.forEach(board->System.out.println(board));
	}

위의 테스트 결과 그림 중 두번째 사진을 보면 'order by board0_.bno asc'로 처리되는 것을 확인할 수 있습니다.

 

2. Page<T> 타입

Spring Data JPA에서 결과 데이터가 여러 개인 경우 List<T> 타입을 이용하기도 하지만, Page<T> 타입을 이용하면 Spring MVC와 연동 시 상당한 편리함을 제공합니다.

 

org.zerock.persistence.BoardRepository 인터페이스에 페이징, 정렬 처리

public interface BoardRepository extends CrudRepository<Board, Long>{
		
	// 게시물의 번호가 특정 숫자 이상인 게시물을 검색
	// 객체타입이 Page<T>이면 getContent() 메서드를 통해서 List<T>를 참조할 수 있음
	public Page<Board> findByBnoGreaterThan(Long bno, Pageable paging);	
}

org.zerock.Boot03ApplicationTests 일부

	@Test
	void testBnoPagingSort() {
		Pageable paging = PageRequest.of(0, 10, Sort.Direction.ASC, "bno");
		
		Page<Board> result = repo.findByBnoGreaterThan(0L, paging);
		
		System.out.println("PAGE SIZE: " + result.getSize());
		System.out.println("TOTAL PAGES: " + result.getTotalPages());
		System.out.println("TOTAL COUNT: " + result.getTotalElements());
		System.out.println("NEXT: " + result.nextPageable());
		
		List<Board> list = result.getContent();
		
		list.forEach(board -> System.out.println(board));
	}

 

Page<T> 타입 메소드

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Page.html

 

Page (Spring Data Core 2.5.5 API)

 Page map(Function  converter) Returns a new Page with the content of the current one mapped by the given Function.

docs.spring.io

 

References

스타트 스프링 부트, 구멍가게 코딩단 저