JPQLの比較演算(LIKE / IN / BETWEEN)の基本と使いどころ【Spring Data JPA初心者向け】
新人
「Spring Data JPAでクエリを書くときに、JPQLというものが出てきました。SQLとは何が違うんでしょうか?」
先輩
「JPQLは、データベースのテーブルではなく、JavaのEntityを基準にして書くクエリなんだ。」
新人
「LIKEやIN、BETWEENも使えるみたいですが、どんな場面で使えばいいのか分からなくて……。」
先輩
「では、JPQLの基本と比較演算の考え方を、初心者向けに整理していこう。」
1. JPQLとは何か(SQLとの違いを含めた基本説明)
JPQLとは、Java Persistence Query Languageの略で、 Spring Data JPAで利用されるクエリ言語です。 SQLに似た書き方をしますが、最大の違いは、 データベースのテーブルではなく、 Javaで定義したEntityを対象にしている点です。
SQLでは、テーブル名やカラム名を直接指定しますが、 JPQLではEntity名やフィールド名を使って検索条件を記述します。 そのため、データベースの種類を意識せずに、 共通の書き方でクエリを記述できるのが特徴です。
SQLを少し触ったことがある初心者にとっては、 「書き方は似ているけれど、考え方が違う」 と感じることが多いポイントです。 JPQLは、あくまでJavaのオブジェクトを操作するための言語だと理解すると、 イメージしやすくなります。
2. JPQLで比較演算が必要になる理由
Webアプリケーションでは、 データをすべて取得するだけでなく、 条件に応じて絞り込む処理が頻繁に発生します。 例えば、名前に特定の文字が含まれているデータだけを表示したり、 複数のIDの中から該当するものを取得したり、 ある範囲の数値や日付に該当するデータを検索したりします。
こうした条件指定を行うために使われるのが、 JPQLの比較演算です。 JPQLでは、LIKE、IN、BETWEENといった演算子を使うことで、 SQLを書かなくても柔軟な検索条件を表現できます。
Spring Data JPA クエリ 初心者の方は、 最初からすべてを覚える必要はありません。 「条件付き検索をするための仕組みが用意されている」 という理解を持つだけでも十分です。
3. LIKE / IN / BETWEENとは何か(全体像)
JPQLの比較演算の中でも、 特によく使われるのがLIKE、IN、BETWEENです。 これらは、それぞれ異なる目的で利用されます。
LIKEは、文字列の一部一致検索を行うための演算子です。 名前やタイトルなど、 あいまいな条件で検索したい場合によく使われます。
INは、複数の値の中に含まれているかどうかを判定する演算子です。 特定のID一覧に該当するデータをまとめて取得したい場面で活躍します。
BETWEENは、数値や日付などが、 ある範囲内に収まっているかどうかを判定します。 金額の範囲検索や、 期間指定の検索などでよく利用されます。
これらの比較演算は、 JPQL 比較演算の基本として押さえておくと、 Spring Data JPAを使った検索処理が一気に理解しやすくなります。 次の章以降で、それぞれの使いどころを具体的に見ていくと、 自然と使い分けができるようになります。
public interface UserRepository extends JpaRepository<User, Long> {
}
@Controller
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
このように、Repositoryはinterfaceとして定義し、 Controllerから利用するだけで、 JPQLによる検索処理を安全に組み込めます。 まずは全体像を理解し、 「JPQLはEntityを基準に条件検索を書くもの」 という考え方に慣れることが大切です。
4. LIKE演算子の基本と使いどころ
LIKE演算子は、文字列の一部が一致しているかどうかを判定するための比較演算です。 JPQL LIKEは、SQLのLIKEと見た目は似ていますが、 対象がテーブルのカラムではなく、Entityのフィールドである点が大きな違いです。
例えば、ユーザー名に特定の文字が含まれているデータを検索したい場合、 完全一致ではなく部分一致が必要になります。 そのような場面でLIKE演算子が活躍します。
SQLに慣れている初心者の方は、 「LIKEは文字列検索に使うもの」 というイメージをそのままJPQLに持ち込んで問題ありません。 ただし、JPQLではEntity名とフィールド名を使う点だけ意識しましょう。
@Query("SELECT u FROM User u WHERE u.name LIKE %:keyword%")
List<User> findByNameLike(@Param("keyword") String keyword);
この例では、UserというEntityのnameフィールドに対して、 指定した文字列を含むデータを検索しています。 JPQL LIKE IN BETWEENの中でも、 LIKEは検索画面や一覧画面で最も使用頻度が高い演算子です。
5. IN演算子の基本と使いどころ
IN演算子は、複数の値の中に含まれているかどうかを判定するための比較演算です。 一つずつ条件を書くのではなく、 まとめて指定したい場合に使われます。
例えば、複数のIDを指定して、 それに該当するユーザー情報をまとめて取得したい場面があります。 そのようなケースでは、 IN演算子を使うことで、コードを非常にシンプルに書けます。
SQLではIN句を使って値を並べますが、 JPQLでは、コレクション型の引数をそのまま渡せる点が特徴です。 これにより、Javaらしい書き方で条件指定ができます。
@Query("SELECT u FROM User u WHERE u.id IN :ids")
List<User> findByIdIn(@Param("ids") List<Long> ids);
IN演算子は、チェックボックスで複数選択された条件や、 権限ごとの対象データを取得する場面などでよく使われます。 Spring Data JPA クエリメソッドを理解するうえでも、 この使いどころを押さえておくと実務に役立ちます。
6. BETWEEN演算子の基本と使いどころ
BETWEEN演算子は、値がある範囲内に含まれているかどうかを判定する比較演算です。 数値や日付を扱う検索条件で特によく使われます。
例えば、登録日が特定の期間内にあるデータや、 金額が一定の範囲に収まっているデータを検索したい場合に、 BETWEEN演算子が便利です。
SQLではカラム名を指定しますが、 JPQLではEntityのフィールド名を使います。 この違いに慣れることで、 JPQLの考え方が一段と理解しやすくなります。
@Query("SELECT u FROM User u WHERE u.age BETWEEN :min AND :max")
List<User> findByAgeBetween(@Param("min") int min, @Param("max") int max);
BETWEENは、範囲検索を分かりやすく表現できる演算子です。 条件が二つある場合でも、 一つの式としてまとめられる点が特徴です。
7. クエリメソッドや@QueryでのJPQL記述例
Spring Data JPAでは、 JPQLを直接書かなくても、 メソッド名からクエリを自動生成する仕組みがあります。 これをクエリメソッドと呼びます。
例えば、LIKEやBETWEENといった条件は、 メソッド名に特定のキーワードを含めることで表現できます。 内部ではJPQLが自動的に組み立てられているため、 開発者は細かい構文を意識する必要がありません。
List<User> findByNameContaining(String keyword);
List<User> findByAgeBetween(int min, int max);
一方で、条件が複雑になる場合や、 明示的にJPQLを書きたい場合には、 @Queryアノテーションを使います。 クエリメソッドと@Queryは、 状況に応じて使い分けることが大切です。
Spring Data JPA クエリメソッドとJPQLの関係を理解すると、 「なぜこのメソッド名で動くのか」 という疑問が解消されていきます。 最初はLIKE、IN、BETWEENの基本的な使いどころを押さえ、 少しずつ応用に進んでいくのがおすすめです。
8. 比較演算を使うときの注意点(NULL・大小比較・曖昧検索)
JPQLで比較演算を使い始めると、初心者が混乱しやすいポイントがいくつか出てきます。 特に注意したいのが、NULLの扱い、大小比較の考え方、そして曖昧検索の挙動です。 これらは、最初に知っておくだけで、つまずきを大きく減らせます。
まずNULLについてですが、JPQLでは、 NULLかどうかを比較演算子で直接判定することはできません。 等しいかどうかではなく、 存在するかどうかという観点で考える必要があります。 そのため、NULLを扱う場合は、 「値が入っていない可能性がある」 という前提を常に意識しましょう。
次に大小比較です。 BETWEENや比較演算子を使う場合、 数値や日付が対象になることがほとんどです。 JPQLでは、Entityのフィールド型に従って比較が行われるため、 型が正しく定義されていないと、 意図しない結果になることがあります。 初心者のうちは、 数値は数値、日付は日付として扱われているかを確認するだけで十分です。
曖昧検索についても注意が必要です。 LIKE演算子を使った検索では、 前後に付ける記号によって結果が大きく変わります。 部分一致なのか、前方一致なのかを、 自分でコントロールしている意識を持つことが大切です。 Spring Data JPA JPQLを使う場合でも、 この基本的な考え方は変わりません。
@Query("SELECT u FROM User u WHERE u.name IS NOT NULL")
List<User> findUsersWithName();
このように、NULLの扱いは特別な書き方になります。 最初は難しく感じるかもしれませんが、 「比較できない値がある」という感覚を持てば十分です。
9. JPQLとクエリメソッドの使い分け方
Spring Data JPAでは、 JPQLを直接書く方法と、 クエリメソッドを使う方法の二つがあります。 どちらを使うべきか迷う初心者は非常に多いです。
基本的な考え方としては、 シンプルな条件検索はクエリメソッド、 少し複雑な条件や明示的な制御が必要な場合はJPQL、 という使い分けがおすすめです。 クエリメソッドは、 メソッド名から処理内容が読み取れるため、 可読性が高いのが特徴です。
一方で、条件が増えすぎると、 メソッド名が長くなりすぎて分かりにくくなります。 そのような場合は、 @Queryを使ってJPQLを書くことで、 検索条件を一か所にまとめられます。 JPQL 比較演算 使いどころを考える際は、 「読みやすさ」を一つの判断基準にするとよいでしょう。
List<User> findByNameContainingAndAgeBetween(String keyword, int min, int max);
このようなメソッドは便利ですが、 条件が増えるほど複雑になります。 最初は無理に使い分けようとせず、 動きを理解することを優先して問題ありません。
10. JPQLの比較演算を使うメリットと限界
JPQLの比較演算を使う最大のメリットは、 SQLを書かずに柔軟な検索条件を表現できる点です。 Entityを基準にした記述になるため、 データベースの構造を強く意識せずに済みます。 これは、Spring Data JPA初心者にとって大きな安心材料です。
また、LIKEやIN、BETWEENといった演算子を使うことで、 実務でよくある検索条件をほぼ網羅できます。 一覧検索、条件検索、範囲検索といった処理は、 JPQLの比較演算だけで十分対応可能です。
一方で、JPQLにも限界はあります。 複雑すぎる条件や、 データベース固有の機能を使いたい場合には、 表現が難しくなることがあります。 ただし、初心者の学習段階では、 そのようなケースを意識する必要はありません。
まずは、 「JPQLでここまでできる」 という感覚を身につけることが大切です。 Spring Data JPA JPQLの強みを理解できれば、 データ検索に対する不安は大きく減っていきます。
11. JPQLを理解した次の学習ステップ
JPQLの比較演算を一通り理解できたら、 次にやるべきことは、 すべてを完璧に覚えようとしないことです。 LIKE、IN、BETWEENの使いどころが分かっていれば、 学習としては十分な段階に来ています。
次のステップとしては、 実際の画面処理と組み合わせて、 検索条件がどのように使われるのかを体験することがおすすめです。 ControllerからRepositoryを呼び出し、 検索結果を画面に表示する流れを何度か書いてみると、 JPQLの理解が一気に深まります。
最初は、 「この条件で検索できた」 という成功体験を積み重ねることが大切です。 比較演算の細かい仕様は、 必要になったときに調べれば問題ありません。
JPQLは、 Spring Data JPAを使ったDB操作の基礎体力になります。 今回学んだ比較演算の考え方を土台に、 少しずつ実装経験を積んでいけば、 自然と検索処理に自信が持てるようになります。 焦らず、一歩ずつ進めていきましょう。