最新の安定バージョンについては、Spring Data Relational 3.4.1 を使用してください! |
クエリメソッド
通常、リポジトリでトリガーするデータアクセス操作のほとんどは、データベースに対して実行されるクエリになります。このようなクエリの定義は、次の例に示すように、リポジトリインターフェースでメソッドを宣言することです。
interface ReactivePersonRepository extends ReactiveSortingRepository<Person, Long> {
Flux<Person> findByFirstname(String firstname); (1)
Flux<Person> findByFirstname(Publisher<String> firstname); (2)
Flux<Person> findByFirstnameOrderByLastname(String firstname, Pageable pageable); (3)
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname); (4)
Mono<Person> findFirstByLastname(String lastname); (5)
@Query("SELECT * FROM person WHERE lastname = :lastname")
Flux<Person> findByLastname(String lastname); (6)
@Query("SELECT firstname, lastname FROM person WHERE lastname = $1")
Mono<Person> findFirstByLastname(String lastname); (7)
}
1 | このメソッドは、指定された firstname を持つすべての人々のクエリを示します。クエリは、And および Or と連結できる制約のメソッド名を解析することによって導出されます。メソッド名は SELECT … FROM person WHERE firstname = :firstname のクエリ式になります。 |
2 | このメソッドは、指定された Publisher によって firstname が発行されると、指定された firstname を持つすべての人々のクエリを示します。 |
3 | Pageable を使用して、オフセットと並べ替えのパラメーターをデータベースに渡します。 |
4 | 指定された条件で単一のエンティティを検索します。一意でない結果の場合は、IncorrectResultSizeDataAccessException で完了します。 |
5 | <4> でない限り、クエリでより多くの結果行が生成された場合でも、最初のエンティティは常に発行されます。 |
6 | findByLastname メソッドは、指定された姓を持つすべての人々のクエリを表示します。 |
7 | firstname および lastname 列のみを投影する単一の Person エンティティの照会。アノテーション付きクエリは、この例では Postgres バインドマーカーであるネイティブバインドマーカーを使用します。 |
@Query
アノテーションで使用される select ステートメントの列は、それぞれのプロパティに対して NamingStrategy
によって生成された名前と一致する必要があることに注意してください。select ステートメントに一致する列が含まれていない場合、そのプロパティは設定されません。そのプロパティが永続性コンストラクターで必要な場合は、null または(プリミティブ型の場合)デフォルト値が提供されます。
次の表は、クエリメソッドでサポートされるキーワードを示しています。
キーワード | サンプル | 論理的な結果 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
クエリの変更
前のセクションでは、特定のエンティティまたはエンティティのコレクションにアクセスするためのクエリを宣言する方法について説明しました。前の表のキーワードを使用すると、delete … By
または remove … By
と組み合わせて、一致する行を削除する派生クエリを作成できます。
Delete … By
クエリ interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
Mono<Integer> deleteByLastname(String lastname); (1)
Mono<Void> deletePersonByLastname(String lastname); (2)
Mono<Boolean> deletePersonByLastname(String lastname); (3)
}
1 | Mono<Integer> の戻り型を使用すると、影響を受ける行の数が返されます。 |
2 | Void を使用すると、結果値を出力せずに行が正常に削除されたかどうかがレポートされるだけです。 |
3 | Boolean を使用すると、少なくとも 1 つの行が削除されたかどうかが報告されます。 |
このアプローチは包括的なカスタム機能に適しているため、次の例に示すように、クエリメソッドに @Modifying
アノテーションを付けることで、パラメーターバインディングのみが必要なクエリを変更できます。
@Modifying
@Query("UPDATE person SET firstname = :firstname where lastname = :lastname")
Mono<Integer> setFixedFirstnameFor(String firstname, String lastname);
変更クエリの結果は次のとおりです。
Void
(または KotlinUnit
)は、更新カウントを破棄して完了を待ちます。影響を受ける行数を出力する
Integer
または別の数値型。少なくとも 1 つの行が更新されたかどうかを出力する
Boolean
。
@Modifying
アノテーションは、@Query
アノテーションと組み合わせた場合にのみ関連します。派生したカスタムメソッドでは、このアノテーションは不要です。
変更クエリは、データベースに対して直接実行されます。イベントやコールバックは呼び出されません。アノテーション付きクエリで更新されない場合、監査アノテーションを含むフィールドも更新されません。
または、Spring Data リポジトリのカスタム実装で説明されている機能を使用して、カスタム変更動作を追加できます。
@Query
を使用する
次の例は、@Query
を使用してクエリメソッドを宣言する方法を示しています。
interface UserRepository extends ReactiveCrudRepository<User, Long> {
@Query("select firstName, lastName from User u where u.emailAddress = :email")
Flux<User> findByEmailAddress(@Param("email") String email);
}
文字列ベースのクエリは、ページネーションをサポートしておらず、クエリパラメーターとして Sort 、PageRequest 、Limit を受け入れないことに注意してください。これらのクエリの場合、クエリを書き直す必要があるからです。制限を適用したい場合は、SQL を使用してこの意図を表現し、適切なパラメーターをクエリにバインドしてください。 |
Spring は、-parameters コンパイラーフラグに基づく Java 8 のパラメーター名の検出を完全にサポートしています。デバッグ情報の代替としてビルドでこのフラグを使用することにより、名前付きパラメーターの @Param アノテーションを省略できます。 |
SpEL 式を使用したクエリ
クエリ文字列定義を SpEL 式と一緒に使用して、実行時に動的クエリを作成できます。SpEL 式は、クエリを実行する直前に評価される述語値を提供できます。
式は、すべての引数を含む配列を通じてメソッド引数を公開します。次のクエリは、[0]
を使用して、lastname
の述語値を宣言します(これは、:lastname
パラメーターバインディングと同等です)。
@Query("SELECT * FROM person WHERE lastname = :#{[0]}")
Flux<Person> findByQueryWithExpression(String lastname);
クエリ文字列の SpEL は、クエリを強化する強力な方法です。しかし、彼らはまた、不要な引数の広い範囲を受け入れることができます。クエリに不要な変更が加えられないように、クエリに渡す前に文字列をサニタイズしてください。
式のサポートは、Query SPI: org.springframework.data.spel.spi.EvaluationContextExtension
を介して拡張可能です。Query SPI は、プロパティと機能を提供し、ルートオブジェクトをカスタマイズできます。拡張機能は、クエリの作成時の SpEL 評価時にアプリケーションコンテキストから取得されます。
SpEL 式をプレーンパラメーターと組み合わせて使用する場合は、ネイティブバインドマーカーの代わりに名前付きパラメーター表記を使用して、適切なバインド順序を確保してください。 |