JPAはメソッド名からクエリを生成してくれるようですが、これは本当にびっくりしたので、メモしていこうと思います。
メソッドで生成キーワード
| キーワード | サンプル | JPQL スニペット |
|---|---|---|
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is、Equals | findByFirstname、findByFirstnameIs、findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull、Null | findByAge(Is)Null | … where x.age is null |
IsNotNull、NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 ( % が付加されたパラメーター) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 ( % が先頭に追加されたパラメーター) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 ( % にラップされたパラメーターバインド) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection<Age> ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstname) = UPPER(?1) |
使い方の例
https://qiita.com/shindo_ryo/items/af7d12be264c2cc4b252
Is / Equals / Not
EmployeeRepository.java
// SELECT e FROM Employee e
Employee findById(Long id);
// SELECT e FROM Employee e WHERE e.firstname = ?1
List<Employee> findByFirstnameEquals(String firstname);
// SELECT e FROM Employee e WHERE e.age = ?1
List<Employee> findByAgeIs(int age);
// SELECT e FROM Employee e WHERE e.lastname != ?1
List<Employee> findByLastnameNot(String lastname);
// SELECT e FROM Employee e WHERE e.department = ?1
List<Employee> findByDepartment(Department department);
フィールドのあとにEquals/Isをつけると完全一致、Notをつけると不一致のレコードを探索します。
大文字小文字が区別されるかは、データベースの照合順序などに依存します。
LessThan / GreaterThan
使用するキーワードはLessThan GreaterThanです。EmployeeRepository.java
// SELECT e FROM Employee e WHERE e.age < ?1
List<Employee> findByAgeLessThan(int age);
// SELECT e FROM Employee e WHERE e.age > ?1
List<Employee> findByAgeGreaterThan(String firstname);
// SELECT e FROM Employee e WHERE e.hiredAt > ?1
List<Employee> findByHiredAtGreaterThan(Date date);
境界値を含む場合は上述のキーワードに「Equal」を足して GreaterThanEqual LessThanEqualとします。
また、 Between キーワードで境界値を含んだ範囲検索が可能です。EmployeeRepository.java
// SELECT e FROM Employee WHERE e.age <= ?1
List<Employee> findByAgeLessThanEqual(int age);
// SELECT e FROM Employee WHERE e.age >= ?1
List<Employee> findByAgeGreaterThanEqual(int age);
// SELECT e FROM Employee WHERE e.hiredAt BETWEEN ?1 AND ?2
List<Employee> findByHiredAtBetween(Date since, Date until);
ちなみに、findByFirstnameLessThan(String name) のように、String型のフィールドにLessThan, GreaterThanをつけることも可能です。結果はDBMS依存になると思いますが。。
Like / NotLike / StartingWith / EndingWith / Containing
// SELECT e FROM Employee WHERE e.firstname LIKE ?1
List<Employee> findByFirstnameLike(int age);
// SELECT e FROM Employee WHERE e.firstname NOT LIKE ?1
List<Employee> findByFirstnameNotLike(String firstname);
// SELECT e FROM Employee WHERE e.lastname LIKE ?1 (前方一致)
List<Employee> findByLastnameStartingWith(String lastname);
// SELECT e FROM Employee WHERE e.lastname LIKE ?1 (後方一致)
List<Employee> findByLastnameEndingWith(String lastname);
// SELECT e FROM Employee WHERE e.lastname LIKE ?1 (部分一致)
List<Employee> findByLastnameContaining(String lastname);
ワイルドカードを使用した部分一致検索は、Like NotLike StartingWith EndingWith Containing を使用します。
このうち、StartingWith EndingWith Containing については、それぞれ順番に、前方一致、後方一致、部分一致となります。
任意の位置にワイルドカードを挿入した場合はLike NotLike を使用してください。
Between
// SELECT e FROM Employee e WHERE e.age BETWEEN ?1 AND ?2
List<Employee> findByAgeBetween(int olderThan, int youngerThan);
// SELECT e FROM Employee e WHERE e.hiredAt BETWEEN ?1 AND ?2
List<Employee> findByHiredAtBetween(Date since, Date until);
IsNull / (Is)NotNull
// SELECT e FROM Employee WHERE e.hiredAt IS NULL
List<Employee> findByHiredAtIsNull();
// SELECT e FROM Employee WHERE e.hiredAt IS NOT NULL
List<Employee> findByHiredAtIsNotNull();
// SELECT e FROM Employee WHERE e.hiredAt IS NOT NULL
List<Employee> findByHiredAtNotNull();
True / False
// SELECT e FROM Employee WHERE e.active = true
List<Employee> findByActiveTrue();
// SELECT e FROM Employee WHERE e.active = false
List<Employee> findByActiveFalse();
IN
// SELECT e FROM Employee WHERE e.lastname in ?1
List<Employee> findByLastnameIn(List<String> lastname);
複数の候補値で検索する場合はSQLと同じくInを使います。
After / Before
// SELECT e FROM Employee WHERE e.lastname > ?1
List<Employee> findByHiredAtAfter(Date date);
// SELECT e FROM Employee WHERE e.lastname < ?1
List<Employee> findByHiredAtBefore(Date date);
日付の比較にはLessThan(Equal) GreaterThan(Equal)が使えますが、After Beforeでも表現可能です。
OrderBy
// SELECT e FROM Employee e WHERE e.lastname = ?1 ORDER BY e.age
List<Employee> findByLastnameOrderByAge(String lastname);
// SELECT e FROM Employee e WHERE e.firstname = ?1 ORDER BY e.firstname ASC
List<Employee> findByFirstnameOrderByHiredAtAsc(String firstname);
抽出結果をソートしたい場合はOrderByを使用します。フィールド名はOrderByのうしろに置きます。昇順降順はさらにフィールド名のうしろに置くので、OrderBy+フィールド名+Asc(Desc)となります。
// SELECT e FROM Employee e WHERE e.lastname = ?1 ORDER BY e.age ASC, e.firstname DESC
List<Employee> findByLastnameOrderByAgeAscFirstnameDesc(String lastname);
複数のフィールドでソートする場合は、Asc Descを指定して、下記のようにつなげればOKです。
Top / First
Employee findFirstByLastname(String lastname);
Employee findTopByLastname(String lastname);
List<Employee> findFirst3ByActiveTrueOrderByAgeDesc();
List<Employee> findTop5ByHiredAtIs(Date date);
findの直後にFirstかTopをつけることで件数を絞ることができます。
組み合わせて使う
// SELECT e FROM Employee e WHERE e.age = ?1, e.active = true
List<Employee> findByAgeIsAndActiveTrue(int age);
// SELECT e FROM Employee e WHERE e.lastname LIKE ?1 OR e.lastname LIKE ?2
List<Employee> findByLastnameStartingWithOrFirstnameEndingWith(String lastname, String firstname);
// SELECT e FROM Employee e WHERE e.age BETWEEN ?1 AND ?2 AND e.department = ?3
List<Employee> findByAgeBetweenAndDepartmentIs(int startAge, int endAge, Department depar
キーワードの組み合わせができます。
終わりに
使い方はこちらから持ってきました。詳しくできているのでそちらを参考にしてください。この記事は、忘れるかもしれないので、メモとして残した記事です。
参考
https://qiita.com/shindo_ryo/items/af7d12be264c2cc4b252
