22
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Data JPA:Repositoryの@QueryにpureなSQLでクエリを記述する

Last updated at Posted at 2018-11-10

TL;DR

Spring Data JPA の @Query に対してnativeQuery = true を指定することで、JPQL ではなくSQLによる問い合わせができるようになります。

public interface PhotoRepository extends JpaRepository<Photo, Integer> {
  @Query(value = "SELECT * FROM PHOTO AS p WHERE p.USER_ID = 1", nativeQuery = true) // SQL
  Iterator<Photo> findPhotosByUserId(int userId);
}

@Repository

Spring Data JPAでは、Repositoryインタフェース内にメソッドを定義+@AutowiredでDIするだけで、RepositoryをDAO、すなわちテーブルアクセスできるオブジェクトとして使用することができます。

PhotoRepository.java
@Repository
public interface PhotoRepository extends JpaRepository<Photo, Integer> {
// PHOTOテーブルがUSER_IDカラムを持つ場合、引数userIdとUSER_IDが一致するレコード取得
  Iterator<Photo> findByUserId(int userId); 
}
PhotoService.java
@Service
public class PhotoService {

  @Autowired // DI:インスタンス化済み
  private PhotoRepository repository;

  public Iterator<Photo> getPhotos(int userId) {
     return repository.findByUserId(userId);
  }

}

(簡単のため、JpaRepositoryを継承したRepositoryを直接使用しています。実際はJpaRepository継承/Entity定義をPhotoRepositoryが置かれるドメイン層から切り離します)

@Repository はSpringにおけるRepositoryコンポーネントであることを表していて、このアノテーションによって @Autowired によるDI対象になります。

ちなみにRepositoryに定義できるメソッドの命名規則は以下参照。
BETWEENとかORDER_BYとかも普通にできます。
Spring Data JPA - Reference Documentation

@Query

Repository上のメソッドに@Queryをつけると、メソッド命名規則からクエリを定義せず、クエリを文字列で直接定義できるようになります。

public interface PhotoRepository extends JpaRepository<Photo, Integer> {
  @Query(value = "select p from photo p where p.userId = 1") // JPQL
  Iterator<Photo> findPhotosByUserId(int userId);
}

ただしデフォルトで定義できるのはJPQLと呼ばれる問い合わせ言語で、SQLではありません。そのため@Queryの引数に普通にSQLを記述してしまうとエラーとなってしまいます。

参考:10.2. JPQL Language Reference

SQLで実行するには、冒頭の通りnativeQuery = true をつけます。これでいつもどおりのSQLを使うことができます。

public interface PhotoRepository extends JpaRepository<Photo, Integer> {
  @Query(value = "SELECT * FROM PHOTO AS p WHERE p.USER_ID = 1", nativeQuery = true) // SQL
  Iterator<Photo> findPhotosByUserId(int userId);
}
22
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?