[JDBC] Pagination ์‹ค์Šต

Updated:

Categories:

Tags: , ,

๐Ÿ“Œ ๊ฐœ์ธ์ ์ธ ๊ณต๊ฐ„์œผ๋กœ ๊ณต๋ถ€๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋ณต์Šตํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
์ •ํ™•ํ•˜์ง€ ์•Š์€ ์ •๋ณด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ๋ฐ”๋ž๋‹ˆ๋‹ค :๐Ÿ˜ธ
[ํ‹€๋ฆฐ ๋‚ด์šฉ์€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๋ณต๋ฐ›์œผ์‹ค๊ฑฐ์—์š”]

Pagination ๊ตฌํ˜„ ์‹ค์Šต

1์ฐจ ์‹œ๋„

Paginaiton์ด ์ฒ˜์Œ์ด๋ผ ์‹ค์Šต ํ•˜๊ธฐ ์ „๋ถ€ํ„ฐ ๋ฏธ๋ฆฌ ๊ฒ€์ƒ‰ํ•ด๋ดค๋Š”๋ฐ ๋‹ค ๋ฌด์Šจ ๋ง์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์–ด์„œ

ํ•œ์ฐธ ๊ฒ€์ƒ‰ํ•˜๋‹ค๊ฐ€ ์ •๋ง ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ posting ๋œ ์‚ฌ์ดํŠธ๊ฐ€ ์žˆ์–ด์„œ ๊ณต์‹ ๋ฌธ์„œ ๊ฐ™์€ ๊ฑด ์ค„ ์•Œ์•˜๋Š”๋ฐ ๋ธ”๋กœ๊ทธ ๊ฐ™์€ ๊ณณ์— ๊ฒŒ์‹œ๋œ ๊ธ€์ด์—ˆ์Œ

๊ทธ๋ž˜๋„ ์ฒ˜์Œ์— ์ ‘๊ทผํ•˜๊ธฐ ์‰ฌ์›Œ์„œ ํ•ด๋‹น ํฌ์ŠคํŠธ๋ฅผ ์ œ์ผ ๋งŽ์ด ์ฐธ๊ณ ํ–ˆ๋‹ค.

https://medium.com/@barisalgun/spring-boot-pagination-524083e699fc

์ผ๋‹จ ์–ด๋–ป๊ฒŒ๋“  ๊ตฌํ˜„ํ•ด๋ณด๊ณ  @Repository ์ž‘์„ฑ ์•ˆํ•ด์„œ ์˜ค๋ฅ˜๋„ ๊ฒช๋‹ค๊ฐ€โ€ฆ

POSTMAN์— ๋“œ๋””์–ด get์š”์ฒญ์„ ํ–ˆ๋‹ค.

Pageinfo๊ฐ€ ์•ˆ ๋‚˜์˜ด

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
31
32
33
34
{
    "data": [
        {
            "memberId": 16,
            "email": "hgd16@gmail.com",
            "name": "ํ™๊ธธ๋™16",
            "phone": "010-1616-1616"
        },
        {
            "memberId": 15,
            "email": "hgd15@gmail.com",
            "name": "ํ™๊ธธ๋™15",
            "phone": "010-1515-1515"
        },
        {
            "memberId": 14,
            "email": "hgd14@gmail.com",
            "name": "ํ™๊ธธ๋™14",
            "phone": "010-1414-1414"
        },
        {
            "memberId": 13,
            "email": "hgd13@gmail.com",
            "name": "ํ™๊ธธ๋™13",
            "phone": "010-1313-1313"
        }
    ],
    "pageInfo": {
        "page": 0,
        "size": 0,
        "totalElements": 0,
        "totalPages": 0
    }
}

์•ˆ๊ทธ๋ž˜๋„ ์ž‘์„ฑํ•˜๋‹ค๊ฐ€ ์ฐœ์ฐœํ–ˆ๋˜ ๋ถ€๋ถ„์ด ์žˆ์—ˆ๋Š”๋ฐ mapper ์ž‘์„ฑ ๋ถ€๋ถ„์—์„œ Dto๋กœ ๋ณ€ํ™˜์‹œ PageInfo์˜ ๊ฐ’์„ ๋ถˆ๋Ÿฌ์™€์•ผ ๋˜๋Š”๋ฐ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์—†์–ด์„œ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋กœ ๋„ฃ์–ด์„œ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™์Œ

1
2
3
4
5
6
  default MemberPageResponseDto membersToMemberPageResponseDto(Page<Member> members){
        //members.getContent() => List<Member>
         MemberPageResponseDto memberPageResponseDto =
                 new MemberPageResponseDto(members.getContent(),new PageInfo());
                return memberPageResponseDto;
    }

PageInfo๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ์‹œ ์ž๋™์œผ๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋“ค์–ด์˜ค๋‚˜,,,? ์ƒ๊ฐํ–ˆ๋Š”๋ฐ

๋‹น์—ฐํžˆ ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๊ณ  ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋‚˜ ์‹ถ์–ด์„œ ์ฐพ์•„๋ณด๋‹ˆ

Page๋Š” Slice๋ฅผ ์ƒ์†๋ฐ›๊ณ  Slice์— ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด์žˆ์–ด์„œ

Page์—์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ.

์ฆ‰ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋“ค์–ด์˜ค๋Š” Pagemembers์—์„œ . ๋งŒ ๋ˆ„๋ฅด๋ฉด ๋‹ค๋‚˜์˜ด..!!!

2์ฐจ ์‹œ๋„ ๋ฐ ๋‹ค๋ฅธ Entity ๊ตฌํ˜„

member์ด์™ธ์— Order์™€ Coffee์—๋„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋จผ์ € ๊ตฌํ˜„ ํ›„ ๋ฆฌํŒฉํ† ๋ง ํ•˜๊ธฐ๋กœ ํ•จ,

coffee ๊ตฌํ˜„ ๋‹คํ•˜๊ณ  ์˜ค๋ฅ˜ ๋งŒ๋‚ฌ๋Š”๋ฐ get ์š”์ฒญ์‹œ 500์—๋Ÿฌ๊ฐ€ ๋‚˜์™”๋‹ค.

๋‹นํ™ฉํ•ด์„œ ์ฝ˜์†”๋ณด๋‹ˆ HttpMediaTypeNotAcceptableException: Could not find acceptable representation ๋ผ๊ณ  ์˜ค๋ฅ˜๋ฉ”์„ธ์ง€ ๋ฐœ์ƒ..

ํ˜น์‹œ ์• ๋„ˆํ…Œ์ด์…˜์ด๋‚˜ ๋ญ ๋น ์ง„๊ฒŒ ์žˆ๋‚˜ ํ•œ์ฐธ ์ฐพ๋‹ค๊ฐ€ ์•Œ๊ฒŒ๋œ ๊ฒƒ์€

DTO ํด๋ž˜์Šค ๋งŒ๋“ค๋ฉด์„œ @Getter ๋น ์ ธ๋จน์Œโ€ฆ!

๋‹ค์‚ฌ ๋‹ค๋‚œ ํ–ˆ์ง€๋งŒ ๋ฌดํŠผ ๋‹ค ๊ตฌํ˜„ํ–ˆ๋Š”๋ฐ ๋ช‡๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด ์žˆ์—ˆ์Œ.

๋ฌธ์ œ์ 

  1. pagination 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๋ฏ€๋กœ ์ˆ˜์ • ํ•„์š”
    1. data๊ฐ€ 20๋ถ€ํ„ฐ์ธ๋ฐ ์‹ค์ œ๋กœ page 1์„ ์กฐํšŒํ•˜๋ฉด ์ž๊พธ 20 ๋ถ€ํ„ฐ ์•ˆ๋‚˜์˜ค๊ณ  ์–ด์ค‘๊ฐ„ํ•œ ์ˆซ์ž๊ฐ€ ์กฐํšŒ๋จ.
    2. paginationํ• ๋•Œ ๊ฐ€์žฅ ์ฒซ ํŽ˜์ด์ง€๋Š” 0์ธ ๊ฒƒ, ์ด๊ฑด ํ•ญ์ƒ ๊ธฐ์–ตํ•˜๊ธฐ.
  2. ์ผ๊ด€๋˜๊ฒŒ ๋™์ž‘ํ•ด์•ผ ํ•จ : PSA ( ์–ด๋–ค ๊ฒƒ์ด ๋“ค์–ด์˜ค๋“  findAll์ด ์ผ๊ด€๋˜๊ฒŒ ๋™์ž‘ํ•ด์•ผ ํ•จ. โ†’ PagingAndSortingRepository ํ™œ์šฉํ•ด๋ณด๊ธฐ
  3. PageResponseDto โ‡’ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ œ๋„ค๋ฆญ ํ™œ์šฉ

Refactoring

page, size ์ˆ˜์ •

  1. coffee์— ๋ฐ์ดํ„ฐ๋Š” 2๊ฐœ ๋“ค์–ด๊ฐ€ ์žˆ๊ณ  coffeeId๋ฅผ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์กฐํšŒํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— page= 1์— size=1๋กœ ์š”์ฒญํ•˜๋ฉด coffeeId๋Š” 2๊ฐ€ ๋‚˜์˜ค๋Š”๊ฒŒ ๋งž๋Š”๋ฐ 1์ด ๋‚˜์˜ด,

  2. ๋ชฐ๋ž๋Š”๋ฐ Pagination์—์„œ page๋Š” 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค๊ณ  ํ•จ.

    ๊ทธ๋ž˜์„œ controller์—์„œ๋Š” page-1, pageinfo์—์„œ .getNumber()์—๋Š” +1๋กœ ์ˆ˜์ •ํ•จ.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
         //Cotroller
         @GetMapping
         public ResponseEntity getCoffees(@Positive @RequestParam(name="page",defaultValue = "1") int page,
                                          @Positive @RequestParam(name="size",defaultValue = "1") int size){
             Pageable pageable = PageRequest.of(page-1, size, Sort.by("coffeeId").descending());
             CoffeePageResponseDtos response = mapper.CoffeesToCoffeePageResponseDtos(coffeeService.findCoffees(pageable));
             return new ResponseEntity<>(response, HttpStatus.OK);
         }
            
         //PageInfo
         new PageInfo(coffees.getNumber()+1,
                     coffees.getSize(),
                     coffees.getNumberOfElements(),
                     coffees.getTotalPages());
    
  3. ๊ฒฐ๊ณผ ์ž˜๋‚˜์˜ด!

PSA ์ ์šฉ โ†’ PagingAndSortingRepository

  1. PagingAndSortingRepository ์€ CrudRepository๋ฅผ ์ƒ์† ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ์‰ฝ๊ฒŒ ์ˆ˜์ • ๊ฐ€๋Šฅ.

    ์‹ค์ œ ๊ตฌํ˜„์ฒด๋Š” SimpleJdbcRepository.class

    findAll์ด ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ.

  2. ๊ทธ๋ž˜์„œ ๋‹ค๋ฅธ ์ฝ”๋“œ ์ˆ˜์ •์—†์ด CrudeRepository ์—์„œ PagingAndSortingRepository๋งŒ ๋ณ€๊ฒฝํ•˜๋ฉด ๋˜๋Š”๋ฐ ๋‚˜๊ฐ™์€ ๊ฒฝ์šฐ Sort ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ํ•˜๊ณ  ์‹ถ์–ด์„œ cotroller์—์„œ ์ถ”๊ฐ€ํ•จ

    1
    
     Pageable pageable = PageRequest.of(page-1, size, Sort.by("coffeeId").descending());
    
  3. PageRequest.of์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์— Sort๊ฐ€ ์—†์„ ๋•Œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์•„๋ฌด๊ฒƒ๋„ ๋„ฃ์ง€ ์•Š์Œ

โœจโœจโœจ~PageResponseDto โ‡’ ์ „์—ญ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ.

  1. ๋น„์Šทํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ์ „์—ญ์œผ๋กœ ๋บ€ ํ›„ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ฐœ์„ ํ•˜๊ธฐ.

  2. ์ „์—ญ์— ์žˆ๋Š” response ํŒจํ‚ค์ง€์— PageResponseDtos๋งŒ๋“ค๊ณ  ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š” mapper์™€ cotroller ์ˆ˜์ •

    1
    2
    3
    4
    5
    6
    
     @AllArgsConstructor
     @Getter
     public class PageResponseDtos <T> {
        private List<T> data;
        private PageInfo pageInfo;
     }
    
    • ์‚ฌ์‹ค ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•œ ์ ์€ ์ž˜ ์—†์–ด์„œ data์— Object ํƒ€์ž… ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค๊ฐ€ ๊ฐ•์‚ฌ๋‹˜ํ•œํ…Œ ์ฝ”๋“œ ๊ฒ€ํ†  ์š”์ฒญ์‹œ Object๋Š” ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค๊ณ  ํ•˜์‹ฌ.
    • ๊ทธ๋ž˜์„œ List๋กœ ์“ฐ๋ ค๊ณ  ํ–ˆ์—ˆ๋Š”๋ฐ ์ž๊พธ ์˜ค๋ฅ˜๋‚˜์„œ ์‚ฌ์šฉ ๋ชปํ–ˆ์—ˆ๋‹ค.
    • ํด๋ž˜์Šค ์ด๋ฆ„์—๋„ ๋ฅผ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ์—๋Ÿฌ๊ฐ€ ์•ˆ๋‚จ!
  3. ์ œ๋„ค๋ฆญ

    • ์ œ๋„ค๋ฆญ ๋Œ€์‹  Object ์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ ์“ฐ๋ฉด ๋„ˆ๋ฌด ์œ„ํ—˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ ์“ฐ๋Š” ๊ฒƒ์ด ์ข‹์Œ.
    • ์ œ๋„ค๋ฆญ์€ ๋ชจ๋“  ํƒ€์ž…์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ œํ•œํ•˜๋Š” ๊ฒƒ โ‡’ ๋ชจ๋“  ํƒ€์ž… ํ—ˆ์šฉ์€ Object.
    • ์ œ๋„ค๋ฆญ์€ ํƒ€์ž…์„ ์ œํ•œํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ, ๋ฐ˜ํ™˜๊ฐ’์ด List๋ผ๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Œ (์ƒํ•˜ํ•œ ์ œํ•œ ์—†์ด๋„)

Comment

์˜ค๋Š˜ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์„ Paginaition ๊ตฌํ˜„ํ•˜๋Š” ์‹ค์Šต๊ณผ ๋ฆฌํŒฉํ† ๋ง ํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ๋Š”๋ฐ

๋ฐฐ์šฐ์ง€ ์•Š์•˜๋˜ ๊ฑธ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ์‰ฝ์ง€ ์•Š์€ ์ผ์ธ ๊ฒƒ ๊ฐ™๋‹คโ€ฆ

Page์™€ Pageable์ด ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ์–ด์„œ ๋‹คํ–‰์ด์ง€ ์‹ค์ œ๋กœ ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•˜๋ผ๊ณ  ํ–ˆ์œผ๋ฉด ์•„์ง๋„ ๋๋‚˜์ง€ ์•Š์•˜์„์ง€๋„โ€ฆ? ๋ชจ๋ฅธ๋‹คโ€ฆ๊ทผ๋ฐ ๊ฐ•์‚ฌ๋‹˜์€ ๊ทธ๊ฒƒ๋„ ๊ตฌํ˜„ํ•  ์ค„ ์•Œ์•„์•ผ ํ•œ๋‹ค๊ณ  ํ•˜์‹ฌ.

๊ทธ๋ฆฌ๊ณ  ์ž๊พธ ๋ธ”๋กœ๊ทธ ๊ธ€์„ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ๊ณต์‹๋ฌธ์„œ๋ž‘ ์ธํ…”๋ฆฌ์ œ์ด์—์„œ ๊ตฌํ˜„์ฒด ๋“ค์–ด๊ฐ€์„œ ํ™•์ธํ•˜๋Š” ๊ฒƒ ์—ฐ์Šตํ•ด์•ผ๊ฒ ๋‹ค.

Spring ์นดํ…Œ๊ณ ๋ฆฌ ๋‚ด ๋‹ค๋ฅธ ๊ธ€ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Leave a comment