# [JPA] ํŽ˜์ด์ง•์— ์‚ฌ์šฉ๋˜๋Š” Page์™€ Slice
Study Repository

[JPA] ํŽ˜์ด์ง•์— ์‚ฌ์šฉ๋˜๋Š” Page์™€ Slice

by rlaehddnd0422

Spring Data JPA์—์„œ ์‚ฌ์šฉํ•˜๋Š” Page์™€ Slice์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Page์— ๋Œ€ํ•ด์„œ๋Š” ์ด ์ „์— JPA๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์งง๊ฒŒ๋‚˜๋งˆ ๋‹ค๋ค„๋ณด์•˜๋Š”๋ฐ, ๋ฌดํ•œ ์Šคํฌ๋กค์„ ๊ตฌํ˜„ํ•  ๋•Œ Slice๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง•์— ์‚ฌ์šฉ๋˜๋Š” Page์™€ Slice์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๊ธฐ๋กํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.


Page, Slice๊ฐ€ ๋ฌด์—‡์ด๊ณ  ์–ด๋””์— ์‚ฌ์šฉ๋ ๊นŒ?

Spring Data JPA๋Š” ํŽ˜์ด์ง•์„ ์œ„ํ•ด ๋‘ ๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•˜๋Š”๋ฐ ์ด๊ฒƒ์ด ๋ฐ”๋กœ Slice์™€ Page์ž…๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํŽ˜์ด์ง•์ด ๋ฌด์—‡์ด๋ƒ ?

์šฐ๋ฆฌ๊ฐ€ ํŽ˜์ด์ง•์ด๋ž€ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋– ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ–ˆ์„ ๋•Œ, ์ „์ฒด ๋ฐ์ดํ„ฐ ์ค‘ ์ผ๋ถ€๋ฅผ ์›ํ•˜๋Š” ์ •๋ ฌ ๋ฐฉ์‹์œผ๋กœ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

ํŽ˜์ด์ง• ์˜ˆ์‹œ - ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰

 

ํŽ˜์ด์ง•์€ ์–ด๋–ป๊ฒŒ ์ ์šฉํ• ๊นŒ?

ํŽ˜์ด์ง• ๊ธฐ๋ฒ• ๊ตฌํ˜„์„ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์•Œ์•„์•ผ ํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • page : ํŽ˜์ด์ง• ๊ธฐ๋ฒ•์ด ์ ์šฉ๋˜์—ˆ์„ ๋•Œ, ์›ํ•˜๋Š” ํŽ˜์ด์ง€ 
  • size : ํ•ด๋‹น ํŽ˜์ด์ง€์— ๋‹ด์„ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜
  • sort : ์ •๋ ฌ ๊ธฐ์ค€

์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ๋ฐ‘์—์„œ ์„ค๋ช…ํ•  Pageable ๊ตฌํ˜„์ฒด์— ๋‹ด์•„ ํŽ˜์ด์ง•์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

Repository ์ฝ”๋“œ์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ณด๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Pageable ๊ฐ์ฒด๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค.

public interface PostRepository extends JpaRepository<Post, Long>, QPostRepository{

    Page<Post> findPageBy(Pageable pageable);

Pageable ๊ฐ์ฒด๋Š” Pagination์„ ์œ„ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด๋กœ Pageable์€ ์ธํ„ฐํŽ˜์ด์Šค์ด๋ฏ€๋กœ Pageable์˜ ๊ตฌํ˜„์ฒด์ธ PageRequest ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ด Pageable ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด์ธ PageRequest ์ƒ์„ฑ์ž์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์œ„์—์„œ ์„œ์ˆ ํ•œ page, size, sort๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ข€ ๋” ๊ตฌ์ฒด์ ์œผ๋กœ ์•Œ์•„๋ด…์‹œ๋‹ค.

 

Controller ๊ณ„์ธต์ž…๋‹ˆ๋‹ค. Pageable๋ฅผ Argument๋กœ ์„ค์ •ํ•ด๋‘๋ฉด, ํ•ด๋‹น ๋ฉ”์†Œ๋“œ์—์„œ Pagination ์ •๋ณด๋ฅผ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, "/postList" GetMapping ์š”์ฒญ ์‹œ page, size, sort๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ํ•จ๊ป˜ ์š”์ฒญํ•˜์—ฌ Paging ์ •๋ณด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@GetMapping("/postList")
public ResponseEntity<PostDto> postList(Pageable pageable){
    Page<PostDto> postList = postService.getPage(pageable);
    return new ResponseEntity<>(postList,HttpStatus.OK);
}

 

Service ๊ณ„์ธต์ž…๋‹ˆ๋‹ค. Controller๊ณ„์ธต์—์„œ ์š”์ฒญํ•œ ํŽ˜์ด์ง• ์ •๋ณด๋ฅผ Pageable ๊ตฌํ˜„์ฒด์— ๋‹ด์•„ Repository ๊ณ„์ธต์— ์ ‘๊ทผํ•˜์—ฌ ํŽ˜์ด์ง•๋œ ์ •๋ณด๋ฅผ ํ† ๋Œ€๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊บผ๋‚ด์˜ต๋‹ˆ๋‹ค.

 

public Page<Post> getPage(Pageable pageable) {
	
    int page = pageable.getPageNumber();
    int size = pageable.getPageSize();
    PageRequest.of(page, size, Sort.by(Sort.Direction.DESC));
    return postRepository.findPageBy(pageable);
}

 

๋งŒ์•ฝ ํด๋ผ์ด์–ธํŠธ๊ฐ€ Page, Size, Sort ์ •๋ณด๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์ฟผ๋ฆฌ์ŠคํŠธ๋ง์œผ๋กœ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์ •๋ ฌ๋˜์ง€ ์•Š์€ 20๊ฐœ์”ฉ ๋ถ„๋ฆฌ๋œ ํŽ˜์ด์ง€ ์ค‘ ์ฒซ ํŽ˜์ด์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด @PageDefault ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽ˜์ด์ง• ์ •๋ณด๊ฐ€ ํ•จ๊ป˜ ์š”์ฒญ๋˜์ง€ ์•Š์„ ๋•Œ์— ๋Œ€๋น„ํ•˜์—ฌ ๊ธฐ๋ณธ์ ์ธ ํŽ˜์ด์ง• ์ •๋ณด๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

+ @PageableDefault

@GetMapping("/postList")
public ResponseEntity<PostDto> postList(@PageableDefault(
            page = 0, size = 10, sort = "id", direction = Sort.Direction.DESC)
            Pageable pageable){
    Page<PostDto> postList = postService.getPage(pageable);
    return new ResponseEntity<>(postList,HttpStatus.OK);
}

 

+ page ์ธ๋ฑ์Šค๋ฅผ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •

ํ”„๋ก ํŠธ์—์„œ๋Š” page index๋ฅผ 1๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ Pageable์€ page index๋ฅผ 0๋ถ€ํ„ฐ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ํ•„์š”์— ๋”ฐ๋ผ ๋ฐ”๊ฟ”์ค„ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

@Configuration
public class CustomPageableConfiguration {
    @Bean
    public PageableHandlerMethodArgumentResolverCustomizer customize() {
        return p -> p.setOneIndexedParameters(true);
    }
}

Sol1. CustomPageableConfiguration ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด pageableHandlerMethodArgumentResolverCustomizer๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ setOneIndexedParameters๋ฅผ true๋กœ ์„ค์ •ํ•˜๋ฉด page ์ธ๋ฑ์Šค๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

spring.data.web.pageable.one-indexed-parameters=true

Sol2. ๋˜๋Š” application-yml ์ด๋‚˜ application-properties ์„ค์ •์— ์œ„ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํŽ˜์ด์ง€ ์ธ๋ฑ์Šค๊ฐ€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํŽ˜์ด์ง€ ์ธ๋ฑ์Šค๋ฅผ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด, ๋‹จ์ˆœํžˆ Controller์—์„œ ๋ฐ›๋Š” Pageable์˜ page๊ฐ’์ด -1๋˜์„œ ์ €์žฅ๋  ๋ฟ์ž…๋‹ˆ๋‹ค.

Pageable ๊ฐ์ฒด๋‚˜ ์ดํ›„ ๋ฐ˜ํ™˜๋ฐ›์€ Slice, Page๊ฐ์ฒด์—์„œ๋Š” page์ธ๋ฑ์Šค๊ฐ€ ์—ฌ์ „ํžˆ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ํŽ˜์ด์ง€ index๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ -1์„ ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์œ ์˜ํ•ด์„œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

 


๊ธฐ๋ณธ์ ์ธ ํŽ˜์ด์ง• ๊ฐœ๋…๊ณผ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ Repository๋ฅผ ๋ณด๋ฉด Page๋ฅผ ๊ฐ์ฒด๋กœ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด์ „์— ์–ธ๊ธ‰ํ•œ Slice๋Š” ์–ธ์ œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋ ๊นŒ์š”?

 

Slice

์‚ฌ์‹ค Page๋Š” Slice๊ณผ ์ƒ์†๊ด€๊ณ„์ž…๋‹ˆ๋‹ค.

public interface Page<T> extends Slice<T> {

 ๋”ฐ๋ผ์„œ Slice๊ฐ€ ๊ฐ€์ง„ ๋ชจ๋“  ๋ฉ”์†Œ๋“œ๋ฅผ Page๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Page๊ฐ€ Slice์™€ ๋‹ค๋ฅธ ์ ์€ ์กฐํšŒ ์ฟผ๋ฆฌ ์ดํ›„ ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ํ•œ๋ฒˆ ๋” ์‹คํ–‰๋œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค.

 

Page interface Method

int getTotalPages();

/**
 * Returns the total amount of elements.
 *
 * @return the total amount of elements
 */
long getTotalElements();

Slice interface Method

public interface Slice<T> extends Streamable<T> {

    int getNumber();

    int getSize();

    int getNumberOfElements();
    List<T> getContent();

    boolean hasContent();

    Sort getSort();

    boolean isFirst();

    boolean isLast();

    boolean hasNext();

    boolean hasPrevious();

    default Pageable getPageable() {
      return PageRequest.of(getNumber(), getSize(), getSort());
    }
    
    Pageable nextPageable();

    Pageable previousPageable();
    
    default Pageable nextOrLastPageable() {
      return hasNext() ? nextPageable() : getPageable();
    }

	default Pageable previousOrFirstPageable() {
      return hasPrevious() ? previousPageable() : getPageable();
    }
}

 

Page vs Slice ์–ด๋–ค ๊ฑธ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

Page๋Š” ๋”ฐ๋ผ์„œ ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Slice์™€ ๋‹ค๋ฅด๊ฒŒ ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋‚˜ ์ „์ฒด ํŽ˜์ด์ง€ ์ˆ˜๊นŒ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•œ ๋ฒˆ ๋” ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ ๋œ๋‹ค๋Š” ์ ์—์„œ ์‚ฌ์šฉ ๋ฐฉ์‹์— ๋”ฐ๋ฅธ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Slice์˜ ๊ฒฝ์šฐ ๋ฌดํ•œ ์Šคํฌ๋กค ๊ตฌํ˜„์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ฏธ์ง€ ์ถœ์ฒ˜: ๋“œ๋ฆฌ๋ธ”

๋ฌดํ•œ ์Šคํฌ๋กค์€ ์šฐ๋ฆฌ๊ฐ€ ์Šคํฌ๋กค ๋ฐ”๊ฐ€ ์•„๋ž˜ ๋์— ๋‹ค๋‹ค๋ฅด๊ฒŒ ๋˜๋ฉด ์ถ”๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ๋ฌดํ•œ ์Šคํฌ๋กค์—์„œ๋Š” ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐํšŒํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ตณ์ด Page๋ฅผ ์จ์„œ ์ฟผ๋ฆฌ๋ฅผ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋‚ ๋ฆด ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. 

 

Page๋Š” ์ „์ฒด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ํ•œ ๋ฒˆ ๋” ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ „์ฒด ํŽ˜์ด์ง€ ๊ฐœ์ˆ˜๋‚˜ ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

 

<์ฐธ๊ณ  ์ž๋ฃŒ>

 

Spring Data JPA์˜ Slice & Page

์ด ๊ธ€์€ ์šฐํ…Œ์ฝ” ๋‹ฌ๋กํŒ€ ํฌ๋ฃจ ํŒŒ๋ž‘์ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. Spring Data JPA์—์„œ๋Š” Pagination์„ ์œ„ํ•œ ๋‘ ๊ฐ€์ง€ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ๋ฐ”๋กœ Slice์™€ Page๋‹ค. Repository ์ฝ”๋“œ๋ฅผ ๋จผ์ € ๋ณด์ž. ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ์ฒด๋ฅผ

dallog.github.io

 

[Spring JPA] Spring Data JPA ์—๊ฒŒ ํŽ˜์ด์ง•์ด๋ž€?

์•ˆ๋…•ํ•˜์„ธ์š”!์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ ์ค‘์— ๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ์œผ๋กœ ํšŒ์› ๋ชฉ๋ก API ๋ฅผ ๊ตฌํ˜„ ์ค‘์— ์žˆ์Šต๋‹ˆ๋‹ค.๊ตฌํ˜„ํ•˜๋‹ค ๋ณด๋‹ˆ, ์ถ”ํ›„ ์ˆ˜ ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋ ํ…๋ฐ, ์–ด๋–ป๊ฒŒ ๋ถ„ํ• ํ•ด์„œ ๊ด€๋ฆฌ์ž์—

velog.io

 

 

[SpringBoot] Spring Data JPA ์—์„œ Page์™€ Slice

๋ฐ”๋กœ PageRequest ๊ฐ์ฒด๊ฐ€ ์ž๋™์œผ๋กœ limit, offset์œผ๋กœ ํŽ˜์ด์ง•ํ•˜๋˜ ์ด์ „ ์ฟผ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.PageRequest ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํŽ˜์ด์ง•์„ ํ• ๋•Œ ๋ฐ˜ํ™˜ํ˜•์œผ๋กœ Page์™€ Slice๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.๋‘ ๊ฐ์ฒด์˜ ๊ฒฐ๊ณผ๋ฌผ

velog.io

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ