1. 概要

単純なクエリの場合、コード内の対応するメソッド名を確認するだけで、クエリがどうあるべきかを簡単に導き出すことができます。

このチュートリアルでは、 Spring DataJPAがメソッドの命名規則の形でこのアイデアをどのように活用するかを探ります。

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

派生メソッド名には、最初のByキーワードで区切られた2つの主要部分があります。

List<User> findByName(String name)

find などの最初の部分はイントロデューサーであり、残りの部分( ByName など)は基準です。

Spring Data JPAは、検索、読み取り、クエリ、カウント、および取得をサポートします。したがって、 queryByName を実行でき、Spring Dataも同じように動作します。

Distinct First 、または Top を使用して重複を削除したり、結果セットを制限したりすることもできます

List<User> findTop3ByAge()

基準部分には、クエリのエンティティ固有の条件式が含まれています。エンティティのプロパティ名と一緒に条件キーワードを使用できます。

すぐにわかるように、式をAndおよびOrと連結することもできます。

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

まず、もちろん Spring DataJPAを使用したアプリケーションが必要です。

そのアプリケーションで、エンティティクラスを定義しましょう。

@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
}

リポジトリも定義しましょう。

Spring Dataリポジトリタイプの1つであるJpaRepositoryを拡張します。

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は、デフォルトでnullパラメーターを処理します。 したがって、等式条件に null 値を渡すと、Springは生成されたSQLでクエリをISNULLとして解釈します。

IsNull キーワードを使用して、ISNULL基準をクエリに追加することもできます。

List<User> findByNameIsNull();
List<User> findByNameIsNotNull();

IsNullIsNotNullもメソッド引数を必要としないことに注意してください。

引数を必要としないキーワードがさらに2つあります。

TrueおよびFalseキーワードを使用して、ブールタイプの等式条件を追加できます。

List<User> findByActiveTrue();
List<User> findByActiveFalse();

もちろん、完全な平等よりも寛大なものが必要な場合もあるので、他に何ができるか見てみましょう。

5. 類似条件キーワード

プロパティのパターンを使用して結果をクエリする必要がある場合、いくつかのオプションがあります。

StartingWith を使用して、値で始まる名前を見つけることができます。

List<User> findByNameStartingWith(String prefix);

大まかに言うと、これは「WHERE name LIKE ‘value%’」に変換されます。

値で終わる名前が必要な場合は、EndingWithが必要です。

List<User> findByNameEndingWith(String suffix);

または、containsを使用して値が含まれている名前を見つけることができます。

List<User> findByNameContaining(String infix);

上記のすべての条件は、事前定義されたパターン式と呼ばれることに注意してください。 したがって、これらのメソッドが呼び出されるときに、引数内に%演算子を追加する必要はありません。

しかし、もっと複雑なことをしているとしましょう。 名前がaで始まり、 b を含み、cで終わるユーザーをフェッチする必要があるとします。

そのために、Likeキーワードを使用して独自のLIKEを追加できます。

List<User> findByNameLike(String likePattern);

そして、メソッドを呼び出すときに、LIKEパターンを渡すことができます。

String likePattern = "a%b%c";
userRepository.findByNameLike(likePattern);

今のところ名前についてはこれで十分です。 Userで他の値を試してみましょう。

6. 比較条件キーワード

さらに、使用することができます未満 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);

ユーザーの生年月日がわかっているので、特定の日付の前または後に生まれたユーザーを照会したい場合があります。

そのためにBeforeAfterを使用します。

List<User> findByBirthDateAfter(ZonedDateTime birthDate);
List<User> findByBirthDateBefore(ZonedDateTime birthDate);

7. 複数の条件式

And およびまたはキーワードを使用して、必要な数の式を組み合わせることができます。

List<User> findByNameOrBirthDate(String name, ZonedDateTime birthDate);
List<User> findByNameOrBirthDateAndActive(String name, ZonedDateTime birthDate, Boolean active);

優先順位は、Javaと同様に、またはの順になります。

Spring Data JPAは、追加できる式の数に制限を課していませんが、ここで夢中になってはいけません。 長い名前は判読できず、維持するのが困難です。 複雑なクエリについては、代わりに@Queryアノテーションをご覧ください。

8. 結果の並べ替え

次に、並べ替えを見てみましょう。

OrderBy を使用して、ユーザーを名前のアルファベット順にソートするように依頼できます。

List<User> findByNameOrderByName(String name);
List<User> findByNameOrderByNameAsc(String name);

昇順はデフォルトの並べ替えオプションですが、代わりにDescを使用して逆に並べ替えることができます。

List<User> findByNameOrderByNameDesc(String name);

9. findOne vs findById in CrudRepository

Springチームは、Spring Boot2.xでCrudRepositoryにいくつかの大きな変更を加えました。 そのうちの1つは、findOneの名前をfindByIdに変更することです。

以前のSpring Boot1.xでは、主キーでエンティティを取得するときにfindOneを呼び出していました。

User user = userRepository.findOne(1);

Spring Boot 2.x以降、findByIdでも同じことができます。

User user = userRepository.findById(1);

findById()メソッドは、CrudRepositoryですでに定義されていることに注意してください。 したがって、CrudRepositoryを拡張するカスタムリポジトリで明示的に定義する必要はありません。

10. 結論

この記事では、SpringDataJPAのクエリ導出メカニズムについて説明しました。 プロパティ条件キーワードを使用して、SpringDataJPAリポジトリに派生クエリメソッドを記述しました。

この記事のソースコードは、GitHubプロジェクトで入手できます。