본문 바로가기
카테고리 없음

230320 TIL

by hbIncoding 2023. 3. 20.

1.  오늘 겪은 에러

 1)page redirect 시에는 GetMapping 을 써줘야한다. @PostMapping 의 경우 원하는 페이지로 갈 수 없다.

	@GetMapping("/detail/buybooks/{bookid}/{quantity}")
	public String Buybook(@PathVariable Long bookid, @PathVariable Long quantity) {

		bookService.bookOrder(bookid, quantity);

		String ans = bookid + "번 책을 " + quantity + " 권 주문한다용";
		System.out.println(ans);

		return "redirect:/main";

	}

2.  페이지네이션

  • 사용자가 요청했을 때 수천,수만,수백만 줄의 데이터를 모두 조회하여 제공하는 건 서버의 부하가 매우 크다.
  • 이를 방지하기 위해 일정 길이로 잘라 일부만 제공한다.

 1)Spring Data JPA가 제공하는 페이지네이션

  • JPA로 페이지네이션 기능을 구현할 때 전체 데이터 개수를 가져와 전체 페이지를 계산하고, 현재 페이지가 몇번째 페이지 인지, 예상치 못한 범위를 요청받았을 때 예외처리도 해야해서 번거롭고 불편하다.
  • 하지만 Spring Data JPA는 이런 페이지 네이션도 추상화 되어있어 페이지 크기와 순서만 전달하면 DB에서 해당 페이지에 해당하는 데이터만 가져올 수 있다.

 2)Pageable과 PageRequest

  • Pageable 과 PageRequest는 Spring data에서 제공하는 페이지네이션 정보를 담기위한 인터페이스와 구현체 이다.

 3)PageRequest 생성

PageRequest page = PageRequest.of(0, 10);
  • (페이지 순서, 페이지의 크기)이다. 페이지 순서는 0부터 시작이다.

 4)Pageable의 ofSize() 스태틱 메소드

Pageable.ofSize(10);
  • 페이지 번호를 0으로 고정하여 페이지 사이즈만 설정한다.

 5)조회 결과 정렬

PageRequest.of(0, 10, Sort.by("price").descending());
PageRequest.of(0, 10, Sort.by(Direction.DESC, "price"));
PageRequest.of(0, 10, Sort.by(Order.desc("price")));
PageRequest.of(0, 10, Direction.DESC, "price");
  • sort 클래스 혹은 sort의 내부 enum 클래스인 Direction을 사용하여 정렬을 설정 할 수 도있다.
  • 여기서 "price"가 정렬 기준이 되는 칼럼 이름이다.
  • 위 코드는 모두 내림차순으로 정렬된 것이다.

 6)Slice와 Page

  • Spring Data JPA 레포지토리에 Pageable을 전달하면, 반환 타입으로 Slice 혹은 Page를 받을 수 있다. 
  • 두 인터페이스 모두 조회 결과를 저장하는 역할을 한다
  • Page는 Slice를 상속받는다.

 7)Slice

  • 전체 페이지 개수를 알아내기 위해서는 count 쿼리가 필요하지만 Slice는 별도로 실행하지 않는다.
  • 무한 스크롤 구현 시 그저 다음 페이지 유무만 확인 하는 용도에 적합하다.
    • 예를들어 페이지당 갯수가 10개일 때 11개를 불러와서 11개째가 있으면 다음 페이지가 있다는 것을 활용한다.

 8)page

  • Slice와 다르게 count 쿼리를 실행하여, 전체 데이터와 페이지 개수를 계산할 수 있다.

 9)Silce와 Page 사용

  • 사용전 공통 코드
@ToString
@NoArgsConstructor
@Getter
@Entity
public class Item {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private int price;

    public Item(final String name, final int price) {
        this.name = name;
        this.price = price;
    }
}
  • Slice의 사용 코드
public interface ItemRepository extends JpaRepository<Item, Long> {

    Slice<Item> findSliceByPrice(int price, Pageable pageable);
}
for (int i = 1; i <= 40; i++) {
    itemRepository.save(new Item("상품" + i, 5000));
}

Slice<Item> itemSlice = itemRepository.findSliceByPrice(5000, PageRequest.of(0, 5));

for (Item item : itemSlice.getContent()) {
    System.out.println(item.getName());
}

//실행결과
상품1
상품2
상품3
상품4
상품5
  • Page 사용 코드
public interface ItemRepository extends JpaRepository<Item, Long> {
		// ...
    Page<Item> findPageByPrice(int price, Pageable pageable);
}
for (int i = 1; i <= 40; i++) {
    itemRepository.save(new Item("상품" + i, 5000));
}

Page<Item> itemPage = itemRepository.findPageByPrice(5000, PageRequest.of(0, 5));

for (Item item : itemPage.getContent()) {
    System.out.println(item.getName());
}

//실행결과
상품1
상품2
상품3
상품4
상품5

3.  ElasticSearch

 1)ElasticSearch와 관계형 데이터베이스의 차이

  • RDB와 다르게 ES에서는 키워드에 대한 위치를 미리 알고있어 빠르게 서치가 가능하다

 2)ElasticSearch와 RDB의  차이

 

 

 

 

4.  참고

 1)pageable : https://hudi.blog/spring-data-jpa-pagination/

 

Spring Data JPA에서의 페이지네이션과 정렬

페이지네이션 (Pagination) 사용자가 요청했을 때 데이터베이스에 있는 수천, 수만, 수백만 줄의 데이터를 모두 조회하여 제공한다면 서버의 부하가 굉장히 클 것이다. 이를 방지하기 위해서 대부

hudi.blog