본문 바로가기
Spring|Spring-boot/Spring-Data-JPA

도메인 컨버터 & 페이징과 정렬

by oncerun 2022. 12. 3.
반응형

도메인 컨버터

 

@GetMapping("/members/{id}")
public String findMember(@PathVariable("id") Member member) {
    return member.getUsername();
}

응? 

 

도메인 클래스 컨버터라고 스프링 데이터 JPA가 제공해주는 기능이다. 

 

이는 도메인 클래스 컨버터가 중간에서 동작하여 실제 엔티티를 반환한다. 

 

도메인 클래스 컨버터도 리파지토리를 사용해서 엔티티를 찾는다. 

 

근데 이는 큰 문제가 하나 있는데 트랜잭션 범위 내에서 가져온 엔티티가 아니라는 점이다.

 

따라서 이 엔티티에 대한 속성 변경에 대해 어떠한 디비 쿼리도 발생하지 않는다.

 

그렇다면 단순 조회용으로 사용하기 위해선 위와 같은 방법은 좋은 선택지가 될 수 있다.

 

페이징과 정렬

 

@GetMapping("/members")
public Page<Member> list(Pageable pageable) {
    Page<Member> all = memberRepository.findAll(pageable);
    return all;
}

 

 

이 기능은 PagingAndSortingRepository에 정의된 메서드 시그니처고 우리가 사용하는 JpaRepository의 상위 인터페이스이다.

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

 
   Iterable<T> findAll(Sort sort);

   Page<T> findAll(Pageable pageable);
}
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T>

 

 

재밌는 점은 쿼리 파라미터로 page, size, sort 등의 변수 값을 넘기면 스프링 부트인 경우 PageRequest 객체를 생성하여 바인딩해준다. 

 

이를 통해 우리는 사이즈, 페이지 등의 부가 정보를 받는 DTO클래스를 생략할 수 있다.

 

page : 0부터 시작하며 현재 페이지를 나타낸다.

 

size : 한 페이지에 노출할 데이터 건수

 

sort : 정렬 조건을 정의한다. sort=id, desc&sort=username, desc

 

기본 값을 변경하고 싶다면? 

 

만약 http 요청 시 어떠한 조건 없이 findAll()를 요청하게 되면 default 값으로 20개를 제공해준다. 

이를 변경하기 위해선 설정을 변경할 수 있다.

 

global 설정

 

application.properties, yml에 설정한다. 

 

spring.data.web.pageable.default-page-size

spring.data.web.pageable.max-page-size 

.. 

 

 

부분 설정

 

@GetMapping("/members")
public Page<Member> list(@PageableDefault(size = 32, sort = "username", direction = Sort.Direction.ASC) Pageable pageable) {
    Page<Member> all = memberRepository.findAll(pageable);
    return all;
}

 

페이징 정보가 둘 이상이면 접두사로 구분한다. 

@Qualifier에 접두사명을 추가하면 된다. 

 

"content":[
{
    "content": [
		{}
    ],
    "pageable": {
        "sort": {
            "sorted": false, // 정렬 상태
            "unsorted": true,
            "empty": true
        },
        "pageSize": 5, // 한 페이지에서 나타내는 원소의 수
        "pageNumber": 0, // 페이지 번호 (0번 부터 시작)
        "offset": 0, // 해당 페이지에 첫 번째 원소의 수
        "paged": true,
        "unpaged": false
    },
    "totalPages": 20, // 페이지로 제공되는 총 페이지 수
    "totalElements": 100, // 모든 페이지에 존재하는 총 원소 수
    "last": false, // 마지막인지 아닌지.
    "number": 0,
    "sort": {
        "sorted": false,
        "unsorted": true,
        "empty": true
    },
    "size": 5,
    "numberOfElements": 5,
    "first": true,
    "empty": false
}

 

content 외 부가적인 정보는 반환 타입이 Page이기 때문이며 이는 오프셋 기반 페이지네이션이기 때문이다.

 

만약 Slice 타입으로 반환했다면 총 페이지와, 총 원소 개수와 같은 필드는 존재하지 않을 것이다.

 

자 이러한 속성을 변경하고 싶다면 spring.data.web.pageable.* 속성에 대해 알아보면된다.

 

https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#spring.data.web.pageable.max-page-size

 

Common Application Properties

 

docs.spring.io

 

 

만약에 더 세세한 요청 정보에 대해 프론트가 정하거나 결정권이 없다면  PageRequest를 직접 정의해서 사용해도 된다.

 

PageRequest.of(1, 30);

 

이 방법이 가장 커스텀하기 좋은 방법일 것이다. 

 

 

반응형

'Spring|Spring-boot > Spring-Data-JPA' 카테고리의 다른 글

Projections  (1) 2022.12.03
스프링 데이터 JPA 구현체를 알아보자.  (0) 2022.12.03
Auditing  (0) 2022.11.30
Custom Repository  (0) 2022.11.30
JPA Hint & Lock  (0) 2022.11.27

댓글