Spring/Spring Data JPA

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

noahkim_ 2024. 8. 2. 10:59

4. Repository Methods Returning Collections or Iterables

Using Streamable as Query Method Return Type

interface PersonRepository extends Repository<Person, Long> {
  Streamable<Person> findByFirstnameContaining(String firstname);
  Streamable<Person> findByLastnameContaining(String lastname);
}

Streamable<Person> result = repository.findByFirstnameContaining("av")
  .and(repository.findByLastnameContaining("ea"));
Streamable
  • 비병렬 스트림을 접근할 수 있는 기능 제공 (Iterable X)
  • filter(), map()

 

Returning Custom Streamable Wrapper Types

  • Streamable 인터페이스 구현
  • Streamable을 인수로 받는 생성자
  • 정적 팩토리 메서드 제공 (of() or valueOf())
class Product {                                         
  MonetaryAmount getPrice() { … }
}

@RequiredArgsConstructor(staticName = "of")
class Products implements Streamable<Product> {         
  private final Streamable<Product> streamable;

  public MonetaryAmount getTotal() {                    
    return streamable.stream()
      .map(Product::getPrice)
      .reduce(Money.of(0), MonetaryAmount::add);
  }

  @Override
  public Iterator<Product> iterator() {                 
    return streamable.iterator();
  }
}

interface ProductRepository extends Repository<Product, Long> {
  Products findAllByDescriptionContaining(String text); 
}

 

Support for Vavr Collections

Vavr 
  • Java library (함수형 프로그래밍)

 

Vavr Collection Type
io.vavr.collection.Seq io.vavr.collection.List java.util.Iterable
io.vavr.collection.Set io.vavr.collection.LinkedHashSet java.util.Iterable
io.vavr.collection.Map io.vavr.collection.LinkedHashMap java.util.Map


5. Streaming Query Results

  • Stream<T> 타입 반환 (쿼리 메서드 결과를 점진적으로 처리 O)
// 커스텀 쿼리를 사용하여 결과를 스트리밍
@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();

// 특정 조건을 만족하는 모든 결과를 스트리밍
Stream<User> readAllByFirstnameNotNull();

// 페이지 단위로 결과를 스트리밍
@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

 

 

Stream Close

  • 사용 후 반드시 닫아야 함 (데이터 리소스를 감싸고 있음)

 

방식
  • 수동: close()
  • 자동: try-with-resources
try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
    stream.forEach(user -> {
        // 각 User 객체에 대해 작업 수행
    });
}

 

 

주의사항

  • 모든 Spring Data 모듈이 Stream<T>를 반환 타입으로 지원하지 않음 (확인 필요)

 

6. Asynchronous Query Results

  • 쿼리 메서드 호출 시, 결과 즉시 반환 (작업 완료 후 사용 O)
  • 비동기적으로 실행됨 (TaskExecutor에 제출됨)(백그라운드 동작)

 

@Async

  • 비동기 쿼리 메서드 정의
@Async
Future<User> findByFirstname(String firstname);

@Async
CompletableFuture<User> findOneByFirstname(String firstname);

 

반환 타입
  • Future
Future<User> future = userRepository.findByFirstname("John");
User user = future.get(); // 쿼리 실행 완료를 기다린 후 결과를 가져옴

 

  • CompletableFuture (콜백 함수 작성 O)
CompletableFuture<User> completableFuture = userRepository.findOneByFirstname("John");
completableFuture.thenAccept(user -> {
	// callback func
    // 쿼리 실행 완료 후 사용자에 대해 작업 수행
});