Spring/Spring Data JPA

[Spring Data JPA] 3-2. JPA Query Methods (5)

noahkim_ 2024. 8. 2. 15:49

8. Scrolling

  • 대규모 결과 집합을 작은 청크 단위로 처리할 수 있음 
  • 모든 결과를 메모리에 로드 X (효율적으로 처리)

 

Window<T>

  • 스크롤링 중 반환되는 청크
  • 현재 청크 데이터 + 위치 정보
  • 다음 Window<T>를 가져옴 (결과 소진까지 반복)
Window<User> users = repository.findFirst10ByLastnameOrderByFirstname("Doe", ScrollPosition.offset());
do {
  for (User u : users) {
    // 사용자 처리
  }
  users = repository.findFirst10ByLastnameOrderByFirstname("Doe", users.positionAt(users.size() - 1));
} while (!users.isEmpty() && users.hasNext());

 

 

Window.positionAt()
  • 현재 스크롤 위치

 

ScrollPosition

  • 스크롤링 작업에서 특정 위치를 나타내기 위함

 

ScrollPosition.offset()
  • (오프셋 기반 스크롤링) 특정 오프셋 위치

 

ScrollPosition.keyset()
  • (키셋 기반 스크롤링) 사용되는 위치

 

Scrolling Type

Offset-based 
  • 특정 위치부터의 데이터 (전체 결과 수 반환 X)
  • DB: 전체 결과 물리화 O (전체 결과를 메모리에 로드 후, 요청시마다 맞는 부분만 잘라서 반환 (offset))
interface UserRepository extends Repository<User, Long> {
  Window<User> findFirst10ByLastnameOrderByFirstname(String lastname, OffsetScrollPosition position);
}

WindowIterator<User> users = WindowIterator.of(position -> repository.findFirst10ByLastnameOrderByFirstname("Doe", position))
  .startingAt(OffsetScrollPosition.initial());

 

 

Keyset-based 
  • DB: 전체 결과 물리화 X (오프셋 기반 단점 보완)
  • 정렬 속성: non-nullable (인덱스 활용)
interface UserRepository extends Repository<User, Long> {
  Window<User> findFirst10ByLastnameOrderByFirstname(String lastname, KeysetScrollPosition position);
}

WindowIterator<User> users = WindowIterator.of(position -> repository.findFirst10ByLastnameOrderByFirstname("Doe", position))
  .startingAt(ScrollPosition.keyset());

 

 


출처