일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 오라클 아키텍처
- 러블리즈
- DBMS
- 레이디스코드
- 장범준
- 6학년 8반 1분단
- oracle
- I'm fine thank you
- 니가 참 좋아
- 스위트라떼
- 악보
- 데이터베이스
- Inside Of Me
- 신입
- 핑거스타일
- SQL 처리
- 천공의 시간
- nginx
- 오라클
- 개발자
- index
- 아이유
- 슬픔의 후에
- db
- IT
- 인덱스
- 기타
- 봄 사랑 벚꽃 말고
- 말 더듬
- DBMS 구성요소
취미로 음악을 하는 개발자
[Spring Framework] 쿼리 메소드 (3) 본문
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package org.zerock.persistence; import java.util.Collection; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.CrudRepository; import org.zerock.domain.Board; public interface BoardRepository extends CrudRepository<Board, Long>{ public List<Board> findBoardByTitle(String title); public Collection<Board> findByWriter(String writer); // 작성자에 대한 Like % 키워드 % public Collection<Board> findByWriterContaining(String writer); // Or 조건의 처리 public Collection<Board> findByTitleContainingOrContentContaining( String title, String content); // Title Like % ? % and Bno > ? public Collection<Board> findByTitleContainingAndBnoGreaterThan( String keyword, Long num); // Bno > ? Order by bno Desc public Collection<Board> findByBnoGreaterThanOrderByBnoDesc(Long bno); // bno > ? Order By bno Desc limit ?, ? public List<Board> findByBnoGreaterThanOrderByBnoDesc(Long bno, Pageable paging); //public List<Board> findByBnoGreaterThan(Long bno, Pageable paging); public Page<Board> findByBnoGreaterThan(Long bno, Pageable paging); } | cs |
쿼리 메소드들에는 모든 쿼리 메소드의 마지막 파라미터로 페이지 처리를 할 수 있는 Pageable 인터페이스와 정렬을 처리하는 Sort 인터페이스를 사용할 수 있다.
Pageable 인터페이스는 말 그대로 페이징 처리에 필요한 정보를 제공한다. 보통 가장 많이 사용하는 것은 org.springframework.data.domain.Pageable 인터페이스를 구현한 클래스 중에 PageRequest 클래스를 이용하는 것이다.
예를 들어, findByBnoGreaterThanOrderByBnoDesc()에 Pageable을 적용하면 아래와 같다.
public List<Board> findByBnoGreaterThanOrderByBnoDesc(Long bno, Pageable paging);
코드는 동일하지만, 파라미터에 Pageable이 적용되어 있고, 리턴 타입으로 Collection<> 대신 List<>를 적용한 것이 달라졌습니다. Pageable 인터페이스가 적용되는 경우, 리턴 타입은 org.springframework.data.domian.Slice(Page) 타입, List 타입을 이용해야 한다.
1 2 3 4 5 6 | @Test public void testBnoOrderByPaging() { Pageable paging = PageRequest.of(0, 10); Collection<Board> results = repo.findByBnoGreaterThanOrderByBnoDesc(0L, paging); results.forEach(board -> System.out.println(board)); } | cs |
Pageable 인터페이스에는 여러 메소드가 존재하기 때문에 이를 구현하는 대신에 PageRequest 클래스를 이용한 것이 편리하다.
참고로 위의 코드에서는 스프링 부트 2.0부터 달라진 코드를 사용하고 있다. (원래는 Pageable paging = new PageRequest(...))
[3번 줄] 첫 번째 페이지(인덱스)가 0부터 시작해서 10개의 데이터를 가져오는 것이다.
실행되는 SQL을 보면 MySQL이라서 자동으로 limit가 적용되는 것을 볼 수 있다. 정렬 처리에는 Pageable 인터페이스와 같이 Sort 클래스를 이용한다. Sort는 쿼리 메소드에서 OrderBy로 처리해도 되지만, Sort를 이용하면 원하는 방향으로 파라미터로 결정할 수 있다.
* 스프링 부트 2.0 기준 PageRequest 생성자
생성자 |
설명 |
PageRequest.of(int page, int size) |
페이지 번호(0부터 시작함), 페이지당 데이터의 수 |
PageRequest(int page, int size, Sort.Direction direction, String.. props) |
페이지 번호, 페이지당 데이터의 수, 정렬 방향, 속성들 |
PageRequest(int page, int size, Sort sort) |
페이지 번호, 페이지당 데이터의 수, 정렬 방향 |
PageRequest의 생성자 중에서 Sort 인터페이스 타입을 파라미터로 전달하면 페이징 처리와 정렬에 대한 처리를 동시에 지정할 수 있다.
public List<Board> findByBnoGreaterThan(Long bno, Pageable paging);
쿼리 메소드에서 OrderBy 없이 Pageable만으로 파라미터로 처리하고 있다. 이것은 PageRequest()를 이용해서 다음과 같이 처리할 수 있다.
1 2 3 4 5 | @Test public void testBnoPagingSort() { Pageable paging = PageRequest.of(0, 10, Sort.Direction.ASC, "bno"); Collection<Board> results = repo.findByBnoGreaterThan(0L, paging); results.forEach(board -> System.out.println(board)); | cs |
[3번 줄] bno의 속성 값을 순서대로 정렬
Page<T> 타입
Spring Data JPA에서 결과 데이터가 여러 개인 경우 List<T> 타입을 이용하기도 하지만, Page<T> 타입을 이용하면 Spring MVC와 연동할 때 상당한 편리함을 제공한다. 방금 전 예제의 리턴 타입을 Page<T>로 작성해본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Test public void testBnoPagingSort() { // Pageable paging = PageRequest.of(0, 10, Sort.Direction.ASC, "bno"); // Collection<Board> results = repo.findByBnoGreaterThan(0L, paging); // results.forEach(board -> System.out.println(board)); 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)); } | cs |
출력문을 자세히 보면 실제로 SQL문이 두 번 실행된다는 것을 볼 수 있다.
처음은 데이터를 추출하기 위해서 실행되지만, 두 번째는 데이터의 개수를 파악하기 위해서 'select count(...)'가 실행되는 것을 볼 수 있다.
리턴 타입을 Page<T>로 하게 되면 웹 페이징에서 필요한 데이터를 한 번에 처리할 수 있기 때문에 데이터를 위한 SQL과 개수를 파악하기 위한 SQL을 매번 작성하는 불편함이 없어진다.
'공대인 > Spring[Boot]' 카테고리의 다른 글
[Spring Framework] 쿼리 메소드 (2) (0) | 2019.10.05 |
---|---|
[Spring Framework] 쿼리 메소드 (1) (0) | 2019.10.03 |
[Spring Framework] Spring Data JPA Repository 테스트 (0) | 2019.10.01 |
[Spring Framework] Spring Data JPA Repository (0) | 2019.09.29 |
[Spring Framework] Spring Data JPA 엔티티 클래스 (Entity Class) (0) | 2019.09.29 |