Spring Data JPAリポジトリの派生クエリメソッド

1. 前書き

単純なクエリの場合、コード内の対応するメソッド名を調べるだけで、クエリの内容を簡単に導き出すことができます。*
このチュートリアルでは、https://www.baeldung.com/the-persistence-layer-with-spring-data-jpa#customquery [Spring Data JPA]がメソッド命名規則の形式でこのアイデアをどのように活用するかを探ります。 。

2. Springの派生クエリメソッドの構造

*派生メソッド名には、最初の_By_キーワードで区切られた2つの主要部分があります:*
List<User> findByName(String name)
最初の部分(_find_など)は_introducer_であり、残り(like _ByName_ –は_criteria._)です。
  • Spring Data JPAは_find、read、query、count_、および_get_をサポートします。*たとえば、queryByName を実行すると、Spring Dataは同じように動作します。

    また、__Distinct、First、__または_Top_を使用して重複を削除するか、https://www.baeldung.com/jpa-limit-query-results#spring-data-jpa [結果セットを制限する]を使用することもできます。
List<User> findTop3ByAge()
*条件部分には、クエリのエンティティ固有の条件式が含まれています。*エンティティのプロパティ名とともに条件キーワードを使用できます。 すぐにわかるように、式を_And_および__Or、__と連結することもできます。

3. サンプルアプリケーション

まず、もちろん、https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa [Spring Data JPAを使用したアプリケーション]が必要です。
そのアプリケーションでは、エンティティークラスを定義しましょう:
@Table(name = "users")
@Entity
class User {
    @Id
    @GeneratedValue
    private Integer id;

    private String name;
    private Integer age;
    private ZonedDateTime birthDate;
    private Boolean active;

    // standard getters and setters
}
そして、リポジトリも定義しましょう。 _JpaRepository、_ link:/spring-data-repositories[Spring Data Repository types]のいずれかを拡張します:
interface UserRepository extends JpaRepository<User, Integer> {}
ここに、派生クエリメソッドをすべて配置します。

4. 平等条件キーワード

完全一致は、クエリで最もよく使用される条件の1つです。 クエリで_ = _またはIS演算子を表すいくつかのオプションがあります。
完全一致条件のキーワードなしでプロパティ名を追加できます。
List<User> findByName(String name);
そして読みやすさのために_Is_または_Equals_を追加できます:
List<User> findByNameIs(String name);
List<User> findByNameEquals(String name);
代わりに不平等を表現する必要がある場合、この追加の読みやすさが役立ちます。
List<User> findByNameIsNot(String name);
これは、_findByNameNot(String)_!よりもかなり読みやすいです!
_null_の等価性は特殊なケースであるため、=演算子を使用しないでください。 Spring Data JPAはデフォルトでlink:/spring-data-jpa-null-parameters[_null_ parameters]を処理します。 したがって、等値条件に_null_値を渡すと、Springは生成されたSQLでクエリをIS NULLとして解釈します。
_IsNull_ keywordを使用して、クエリにIS NULL基準を追加することもできます。
List<User> findByNameIsNull();
List<User> findByNameIsNotNull();
_IsNull_も_IsNotNull_もメソッド引数を必要としないことに注意してください。
引数を必要としないキーワードがさらに2つあります。 _True_および_False_キーワードを使用して、_boolean_型の等価条件を追加できます。
List<User> findByActiveTrue();
List<User> findByActiveFalse();
もちろん、正確な平等よりも寛大なものが必要な場合があります。他に何ができるか見てみましょう。

5. 類似条件キーワード

プロパティのパターンを使用して結果を照会する必要がある場合、いくつかのオプションがあります。
_StartingWith_を使用して、値で始まる名前を見つけることができます。
List<User> findByNameStartingWith(String prefix);
大体、これは「WHERE _name_ LIKE _’value% '_」に変換されます。
値で終わる名前が必要な場合、_EndingWith_が必要です。
List<User> findByNameEndingWith(String suffix);
または、_Containing_を使用して、どの名前に値が含まれているかを見つけることができます。
List<User> findByNameContaining(String infix);
上記のすべての条件は、定義済みのパターン式と呼ばれることに注意してください。 したがって、これらのメソッドが呼び出されたときに、引数内に__%__operatorを追加する必要はありません。
しかし、もっと複雑なことをしているとしましょう。 名前が_a_で始まり、_b、_を含み、_c._で終わるユーザーを取得する必要があるとします
そのために、_Like_キーワードを使用して独自のLIKEを追加できます。
List<User> findByNameLike(String likePattern);
そして、メソッドを呼び出すときにLIKEパターンを渡すことができます。
String likePattern = "a%b%c";
userRepository.findByNameLike(likePattern);
今のところ名前についてはこれで十分です。 _User._の他の値を試してみましょう

6. 比較条件キーワード

さらに、_LessThan_および_LessThanEqual_キーワードを使用して、_ <_および_ <= _演算子を使用してレコードを指定された値と比較できます。
List<User> findByAgeLessThan(Integer age);
List<User> findByAgeLessThanEqual(Integer age);
一方、反対の状況では、_GreaterThan_および_GreaterThanEqual_キーワードを使用できます。
List<User> findByAgeGreaterThan(Integer age);
List<User> findByAgeGreaterThanEqual(Integer age);
または、_Between_を使用して2才以上のユーザーを見つけることができます。
List<User> findByAgeBetween(Integer startAge, Integer endAge);
_In_の使用に対して一致する年齢のコレクションを提供することもできます。
List<User> findByAgeIn(Collection<Integer> ages);
ユーザーの生年月日がわかっているため、特定の日付より前または後に生まれたユーザーを照会することができます。 そのために_Before_と_After_を使用します。
List<User> findByBirthDateAfter(ZonedDateTime birthDate);
List<User> findByBirthDateBefore(ZonedDateTime birthDate);

7. 複数の条件式

_And_および_Or_キーワードを使用して、必要な数の式を組み合わせることができます。
List<User> findByNameOrBirthDate(String name, ZonedDateTime birthDate);
List<User> findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);
優先順位は_And_であり、___ Or、is__Javaと同じです。
  • Spring Data JPAでは、追加できる式の数に制限はありませんが、ここで気を狂わせないでください。長い名前は判読できず、維持するのが困難です。 複雑なクエリについては、代わりに https://www.baeldung.com/spring-data-jpa-query [@Query] _アノテーションをご覧ください。*

8. 結果の並べ替え

次はソートです。 _OrderBy_を使用して、ユーザーを名前のアルファベット順にソートするように依頼できます。
List<User> findByNameOrderByName(String name);
List<User> findByNameOrderByNameAsc(String name);
昇順はデフォルトの並べ替えオプションですが、代わりに_Desc_を使用して逆順に並べ替えることができます。
List<User> findByNameOrderByNameDesc(String name);

9. CrudRepository_の_findOne vs findById

Springチームは、Spring Boot _2.x_でlink:/spring-data-repositories#crudrepository[_CrudRepository_]にいくつかの大きな変更を加えました。 それらの1つは、_findOne_の名前を_findById._に変更しています。
以前のSpring Boot 1.xでは、主キーでエンティティを取得したいときに_findOne_を呼び出していました。
User user = userRepository.findOne(1);
Spring Boot 2.x以降、_findById_でも同じことができます。
User user = userRepository.findById(1);
__findById()__methodはすでに_CrudRepository_で定義されていることに注意してください。 したがって、_CrudRepository_を拡張するカスタムリポジトリで明示的に定義する必要はありません。

10. 結論

この記事では、Spring Data JPAのクエリ派生メカニズムについて説明しました。 プロパティ条件キーワードを使用して、Spring Data JPAリポジトリに派生クエリメソッドを記述しました。
このチュートリアルのソースコードは、https://github.com/eugenp/tutorials/tree/master/persistence-modules/spring-data-jpa-2 [Githubプロジェクト]で入手できます。