カテゴリ: Spring 更新日: 2025/11/03

SpringのJPQLと@Queryの使い方を完全ガイド!ネイティブSQLとの違いも解説

JPQL/@Queryの書き方と実例:ネイティブSQLとの使い分け
JPQL/@Queryの書き方と実例:ネイティブSQLとの使い分け

先生と生徒の会話形式で理解しよう

生徒

「SpringでSQLっぽいことをしたいときって、どうやって書けばいいんですか?」

先生

「Spring Data JPAでは、JPQLというクエリ言語や@Queryアノテーションを使って柔軟にデータを取得できますよ。」

生徒

「SQLとは違うんですか?ネイティブSQLとの違いも知りたいです!」

先生

「では、JPQLとネイティブSQLの違い、@Queryの使い方、使い分けについて一緒に見ていきましょう。」

1. JPQLとは?SQLとの違いを解説

1. JPQLとは?SQLとの違いを解説
1. JPQLとは?SQLとの違いを解説

JPQL(Java Persistence Query Language)は、Javaのエンティティクラスを操作するためのクエリ言語です。SQLと構文は似ていますが、テーブル名ではなくエンティティ名やフィールド名を使います。

たとえば、ユーザーをID順に取得するJPQLは以下のようになります。


@Query("SELECT u FROM User u ORDER BY u.id ASC")
List<User> findAllUsers();

このように、Userというのはテーブルではなくエンティティ名を指しています。u.idもカラムではなく、エンティティのプロパティ名です。

2. @QueryアノテーションでJPQLを使う方法

2. @QueryアノテーションでJPQLを使う方法
2. @QueryアノテーションでJPQLを使う方法

Spring Data JPAでは、@Queryアノテーションを使うことで、メソッド名に依存しないクエリを自由に記述できます。

例えば、「名前でユーザーを検索する」場合は以下のように記述します。


@Query("SELECT u FROM User u WHERE u.name = :name")
User findByName(@Param("name") String name);

:nameはパラメータで、@Paramで指定することで値をバインドできます。JPQLでは型安全なエンティティベースの記述ができ、リファクタにも強く、保守性も高いのが特長です。

3. ネイティブSQLの使い方と@QueryのnativeQuery属性

3. ネイティブSQLの使い方と@QueryのnativeQuery属性
3. ネイティブSQLの使い方と@QueryのnativeQuery属性

JPQLではできない複雑なSQLやデータベース固有の関数を使いたいときには、ネイティブSQL(生のSQL)を使うことができます。@QuerynativeQuery = trueを指定することで可能です。


@Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
User findByEmail(String email);

この場合、テーブル名はusersのように実際のデータベースのスキーマ名を使用します。エイリアスもSQLの書き方と同様に使えます。

4. JPQLとネイティブSQLの使い分けポイント

4. JPQLとネイティブSQLの使い分けポイント
4. JPQLとネイティブSQLの使い分けポイント

JPQLとネイティブSQLは、使い分けが重要です。以下のような基準で選ぶと良いでしょう。

  • JPQLを使う場面:基本的な検索・更新・削除、エンティティベースで完結する処理
  • ネイティブSQLを使う場面:データベースの特有の構文、複雑な結合や関数、パフォーマンスチューニング

例えば、PostgreSQLのjsonbやMySQLのLIMITなどはJPQLでは扱いづらいため、ネイティブSQLが必要です。

5. JPQLでのJOIN文の書き方と注意点

5. JPQLでのJOIN文の書き方と注意点
5. JPQLでのJOIN文の書き方と注意点

JPQLでもJOINを使ってテーブル(エンティティ)間のリレーションを扱うことができます。


@Query("SELECT o FROM Order o JOIN o.customer c WHERE c.name = :name")
List<Order> findOrdersByCustomerName(@Param("name") String name);

このように、JOINではエンティティのプロパティをたどる形で記述します。SQLのようにテーブル名を直書きすることはありません。

6. DTOを使ったJPQLクエリの書き方

6. DTOを使ったJPQLクエリの書き方
6. DTOを使ったJPQLクエリの書き方

JPQLでは、DTO(データ転送オブジェクト)を使って必要なフィールドだけを取り出すこともできます。クエリ内でnewを使ってDTOを生成します。


@Query("SELECT new com.example.dto.UserDto(u.name, u.email) FROM User u")
List<UserDto> findUserDtos();

この形式は、パフォーマンスを意識した設計にも有効で、必要なカラムだけを選択してデータ転送量を最適化できます。

7. @Modifyingと@Queryの組み合わせで更新系JPQLを書く

7. @Modifyingと@Queryの組み合わせで更新系JPQLを書く
7. @Modifyingと@Queryの組み合わせで更新系JPQLを書く

更新系クエリ(UPDATE/DELETE)は@Modifyingアノテーションを併用して書きます。トランザクション制御も必要なので注意しましょう。


@Transactional
@Modifying
@Query("UPDATE User u SET u.status = :status WHERE u.id = :id")
void updateUserStatus(@Param("id") Long id, @Param("status") String status);

@Transactionalをメソッドに付けることで、更新クエリがトランザクション内で安全に実行されます。

8. @Queryを使うときのよくあるエラーと対処法

8. @Queryを使うときのよくあるエラーと対処法
8. @Queryを使うときのよくあるエラーと対処法

JPQL/ネイティブSQLの@Queryでありがちなエラーには以下のようなものがあります。

  • エンティティ名とテーブル名の混同(JPQLではエンティティ名)
  • ネイティブSQLなのにnativeQuery = trueを付け忘れ
  • 引数の名前と:paramの不一致

こうしたエラーはIDEの補完やユニットテストで事前に気づくようにすると、開発効率が上がります。

カテゴリの一覧へ
新着記事
Javaのラムダ式で戻り値とvoidの使い方を解説!returnの書き方も完全理解
Javaのメソッド参照とコンストラクタ参照の使い方を完全ガイド!初心者向けに::とClass::newを解説
Javaのラムダ式の書き方を徹底解説!アロー演算子->の基本と使い方
Thymeleafのth:eachの使い方!ループ回数やindexなどの繰り返し処理を学ぼう
人気記事
No.1
Java&Spring記事人気No1
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Spring Boot JPA入門:エンティティ/リポジトリの基本と作り方
No.3
Java&Spring記事人気No3
Javaの@Validアノテーションを徹底解説!初心者でもわかる入力値検証の基本
No.4
Java&Spring記事人気No4
Springの@Repositoryアノテーションの使い方を徹底解説!初心者でもわかるSpringフレームワークのデータアクセス