従来、大量のデータをフェッチすると、結果セット全体をメモリにロードすることが多くなるため、メモリ リソースに負担がかかる可能性があります。
=>;ストリーム クエリ メソッドは、Java 8 Streams を使用してデータを段階的に処理する方法を提供することで、ソリューションを提供します。これにより、常にデータの一部のみがメモリに保持されるようになり、パフォーマンスとスケーラビリティが向上します。
このブログ投稿では、Spring Data JPA でストリーム クエリ メソッドがどのように機能するかを詳しく掘り下げ、そのユースケースを調査し、その実装を示します。
このガイドでは次のものを使用します:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
注: より詳細な例については、こちらの GitHub リポジトリにアクセスしてください
Spring Data JPA のストリーム クエリ メソッドを使用すると、クエリ結果をリストや他のコレクション型ではなくストリームとして返すことができます。このアプローチにはいくつかの利点があります。
効率的なリソース管理: データは段階的に処理され、メモリのオーバーヘッドが削減されます。
遅延処理: 結果はオンデマンドでフェッチされ、処理されます。これは、ページネーションやバッチ処理などのシナリオに最適です。
関数型プログラミングとの統合: ストリームは Java の関数型プログラミング機能に適合し、フィルター、マップ、収集などの操作を可能にします。
=>;電子商取引アプリケーションを開発していて、次のことをしたいと想像してみましょう。
エンティティ
@Setter @Getter @Entity @Entity(name = "tbl_customer") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Order> orders; }
@Setter @Getter @Entity(name = "tbl_order") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Double amount; private LocalDateTime orderDate; @ManyToOne @JoinColumn(name = "customer_id") private Customer customer; }
リポジトリ
public interface CustomerRepository extends JpaRepository<Customer, Long> { @Query(""" SELECT c FROM tbl_customer c JOIN FETCH c.orders o WHERE o.orderDate >= :startDate """) @QueryHints( @QueryHint(name = AvailableHints.HINT_FETCH_SIZE, value = "25") ) Stream<Customer> findCustomerWithOrders(@Param("startDate") LocalDateTime startDate); }
注:
JOIN FETCH により、注文は積極的にロードされます。
JPA に追加のヒントを提供するために使用される @QueryHints (Hibernate など) は、クエリの実行を最適化します。
=>;たとえば、クエリが 100 レコードを返した場合:
サービス
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
これは、startDate と minOrderAmount の 2 つのパラメーターを使用してデータを処理するサービス クラスです。ご覧のとおり、SQL クエリを使用してフィルタリングすることはなく、すべてのデータをストリームとしてロードし、Java コードでフィルタリングしてグループ化します。
コントローラー
@Setter @Getter @Entity @Entity(name = "tbl_customer") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Order> orders; }
テスト
=>;テスト用のデータを作成するには、ソース コード内で次のスクリプトを実行するか、自分で追加することができます。
src/main/resources/dummy-data.sql
リクエスト:
@Setter @Getter @Entity(name = "tbl_order") public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Double amount; private LocalDateTime orderDate; @ManyToOne @JoinColumn(name = "customer_id") private Customer customer; }
応答:
public interface CustomerRepository extends JpaRepository<Customer, Long> { @Query(""" SELECT c FROM tbl_customer c JOIN FETCH c.orders o WHERE o.orderDate >= :startDate """) @QueryHints( @QueryHint(name = AvailableHints.HINT_FETCH_SIZE, value = "25") ) Stream<Customer> findCustomerWithOrders(@Param("startDate") LocalDateTime startDate); }
=>; IntelliJ Profiler を使用して、メモリ使用量と実行時間を監視できます。大規模なデータセットを追加してテストする方法の詳細については、私の GitHub リポジトリを参照してください
小規模データセット: (顧客 10 人、注文 100 件)
大規模なデータセット (顧客 10,000、注文 100,000)
パフォーマンス指標
Metric | Stream | List |
---|---|---|
Initial Fetch Time | Slightly slower (due to lazy loading) | Faster (all at once) |
Memory Consumption | Low (incremental processing) | High (entire dataset in memory) |
Memory Consumption | Low (incremental processing) | High (entire dataset in memory) |
Processing Overhead | Efficient for large datasets | May cause memory issues for large datasets |
Batch Fetching | Supported (with fetch size) | Not applicable |
Error Recovery | Graceful with early termination | Limited, as data is preloaded |
Spring Data JPA ストリーム クエリ メソッドは、Java Streams の機能を活用しながら、大規模なデータセットを効率的に処理するエレガントな方法を提供します。データを段階的に処理することでメモリ消費を削減し、最新の関数型プログラミング パラダイムとシームレスに統合します。
ストリームクエリメソッドについてどう思いますか?以下のコメント欄であなたの経験や使用例を共有してください!
次の投稿でお会いしましょう。コーディングを楽しんでください!
以上がSpring Data JPA ストリームのクエリ メソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。