베오
DCode
베오
전체 방문자
오늘
어제
  • 분류 전체보기 (218)
    • 공지사항 (1)
    • 잡설 (1)
    • Programming (33)
      • [C] (1)
      • [Java] (4)
      • [Python] (2)
      • [Android] (2)
      • [Network] (0)
      • [Operation System] (2)
      • [Spring Boot] (22)
      • [Docker] (0)
    • Algorithm (31)
      • 자료구조 (2)
      • 알고리즘 (Java) (14)
      • 알고리즘 (기초) (15)
    • Coding Test (131)
      • BOJ (131)
      • Algospat (0)
    • 이론적인거 (14)
      • 보안 (5)
      • 오류 해결 (2)
      • 디자인 패턴 (5)
      • 네트워크 (1)
      • 기타 (1)
    • 최신기술 (4)
      • 블록체인 (1)
    • [Project] (1)

블로그 메뉴

  • 🐈‍⬛ GitHub
  • 📫 방명록
  • 🔖 태그

공지사항

인기 글

티스토리

hELLO · Designed By 정상우.
베오

DCode

Programming/[Spring Boot]

[Spring Data JPA] - 정렬과 페이징 처리

2023. 3. 30. 18:26

정렬 처리

단순 오름차 내림차 정렬

// Acs : 오름차순, Desc : 내림차순
List<Product> findByNameOrderByNumberAsc(String name); // name인 Product를 찾되, Number기준으로 오름차순 정렬한다.
List<Product> findByNameOrderByNumberDesc(String name); // name인 Product를 찾되, Number기준으로 내림차순 정렬한다.

다중 오름차 내림차 정렬

조건절에서 And, Or 붙이는 것과 다르게 여기서는 And, Or을 붙이지 않는다.

// And를 붙이지 않음
List<Product> findByNameOrderByPriceAscStockDesc(String name); // name 인 Product 를 찾되, Price 기준으로 오름차순, Stock 기준으로 내림차순 정렬한다.

다중 오름차 내림차 정렬

정렬 조건이 많아지면, 메서드명이 길어지는 문제가 생긴다.

→ 가독성 감소

이를 해결하기 위한 방법을 알아보자

// Sort 객체 전달하여 정렬하기
List<Product> findByName(String name, Sort sort);

아래 코드는 테스트 코드이다.


package com.springboot.advanced_jpa.data.repository;

import com.springboot.advanced_jpa.data.entity.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;


import java.time.LocalDateTime;

@SpringBootTest
public class ProductRepositoryTest {
    @Autowired
    ProductRepository productRepository;

    @Test
    void sortingAndPagingTest() {
        Product product1 = new Product();
        product1.setName("펜");
        product1.setPrice(1000);
        product1.setStock(100);
        product1.setCreatedAt(LocalDateTime.now());
        product1.setUpdatedAt(LocalDateTime.now());

        Product product2 = new Product();
        product2.setName("펜");
        product2.setPrice(5000);
        product2.setStock(300);
        product2.setCreatedAt(LocalDateTime.now());
        product2.setUpdatedAt(LocalDateTime.now());

        Product product3 = new Product();
        product3.setName("펜");
        product3.setPrice(500);
        product3.setStock(50);
        product3.setCreatedAt(LocalDateTime.now());
        product3.setUpdatedAt(LocalDateTime.now());

        Product savedProduct1 = productRepository.save(product1);
        Product savedProduct2 = productRepository.save(product2);
        Product savedProduct3 = productRepository.save(product3);

        productRepository.findByName("펜", Sort.by(Order.asc("price")));
        productRepository.findByName("펜", Sort.by(Order.asc("price"), Order.desc("stock")));
    }
}

다음과 같이 정렬이 가능하다.

Sort.by(Order.asc(”컬럼명”))

Sort.by(Order.asc(”컬럼명”), Order.desc(”컬럼명2”))

정렬 부분을 분리해보자

getSort() 메서드를 따로 정의해서 상황에 맞게 정렬하여 반환이 가능하도록 하자.

package com.springboot.advanced_jpa.data.repository;

import com.springboot.advanced_jpa.data.entity.Product;
import org.aspectj.weaver.ast.Or;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;


import java.time.LocalDateTime;

@SpringBootTest
public class ProductRepositoryTest {
    @Autowired
    ProductRepository productRepository;

    @Test
    void sortingAndPagingTest2() {
        Product product1 = new Product();
        product1.setName("펜");
        product1.setPrice(1000);
        product1.setStock(100);
        product1.setCreatedAt(LocalDateTime.now());
        product1.setUpdatedAt(LocalDateTime.now());

        Product product2 = new Product();
        product2.setName("펜");
        product2.setPrice(5000);
        product2.setStock(300);
        product2.setCreatedAt(LocalDateTime.now());
        product2.setUpdatedAt(LocalDateTime.now());

        Product product3 = new Product();
        product3.setName("펜");
        product3.setPrice(500);
        product3.setStock(50);
        product3.setCreatedAt(LocalDateTime.now());
        product3.setUpdatedAt(LocalDateTime.now());

        Product savedProduct1 = productRepository.save(product1);
        Product savedProduct2 = productRepository.save(product2);
        Product savedProduct3 = productRepository.save(product3);

        System.out.println(productRepository.findByName("펜", getSort()));
    }

    private Sort getSort() {
        return Sort.by(
                Order.asc("price"),
                Order.desc("stock")
        );
    }
}

페이징 처리

페이징이란?

💡
데이터베이스의 레코드를 개수로 나눠 페이지를 구분하는 것

페이징 왜 쓰는데?

→ 데이터베이스 내에 많은 데이터를 한번에 처리하기 어렵기 때문

JPA 에서는 페이징 처리를 하기 위해 Page, Pageable을 사용한다.

Repository에서는 다음과 같이 정의한다.

// 페이징을 위한 쿼리 메서드
Page<Product> findByName(String name, Pageable pageable);

요청은 다음과 같이 한다.

Page<Product> productPage = productRepository.findByName("펜", PageRequest.of(0,2));

PageRequest.of 메서드를 살펴보자

of 메서드매개변수 설명비고
of(int page, int size)페이지 번호(0부터 시작), 페이지당 데이터 개수데이터를 정렬하지 않음
of(int page, int size, Sort sort)페이지 번호(0부터 시작), 페이지당 데이터 개수, 정렬sort에 의해 정렬

Page 객체의 데이터를 출력해보자

Page 의 getContent() 메서드를 이용하여 배열 형태로 값을 출력한다.

Page<Product> productPage = productRepository.findByName("펜", PageRequest.of(0,2));
        System.out.println(productPage.getContent());

        productPage = productRepository.findByName("펜", PageRequest.of(1,2));
        System.out.println(productPage.getContent());

출력한 결과는 다음과 같다.

Hibernate: 
    select
        product0_.number as number1_0_,
        product0_.created_at as created_2_0_,
        product0_.name as name3_0_,
        product0_.price as price4_0_,
        product0_.stock as stock5_0_,
        product0_.updated_at as updated_6_0_ 
    from
        product product0_ 
    where
        product0_.name=? limit ?
Hibernate: 
    select
        count(product0_.number) as col_0_0_ 
    from
        product product0_ 
    where
        product0_.name=?
[Product(number=1, price=1000, stock=100, createdAt=2023-03-30T17:31:27.534225, updatedAt=2023-03-30T17:31:27.534225), Product(number=2, price=5000, stock=300, createdAt=2023-03-30T17:31:27.534225, updatedAt=2023-03-30T17:31:27.534225)]
Hibernate: 
    select
        product0_.number as number1_0_,
        product0_.created_at as created_2_0_,
        product0_.name as name3_0_,
        product0_.price as price4_0_,
        product0_.stock as stock5_0_,
        product0_.updated_at as updated_6_0_ 
    from
        product product0_ 
    where
        product0_.name=? limit ?, ?
[Product(number=3, price=500, stock=50, createdAt=2023-03-30T17:31:27.534225, updatedAt=2023-03-30T17:31:27.534225)]


Uploaded by N2T

'Programming > [Spring Boot]' 카테고리의 다른 글

[Spring Data JPA] - JPA Auditing  (0) 2023.03.30
Spring Data JPA 활용하기  (0) 2023.03.29
[Spring Data JPA] - 쿼리 메서드의 주제(Subject) 키워드  (0) 2023.03.29
[Spring Data JPA] - 쿼리 메서드의 조건자 키워드  (0) 2023.03.29
테스트 주도 개발(TDD)  (0) 2023.03.16
    'Programming/[Spring Boot]' 카테고리의 다른 글
    • [Spring Data JPA] - JPA Auditing
    • Spring Data JPA 활용하기
    • [Spring Data JPA] - 쿼리 메서드의 주제(Subject) 키워드
    • [Spring Data JPA] - 쿼리 메서드의 조건자 키워드
    베오
    베오

    티스토리툴바