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、すなわちテーブルアクセスできるオブジェクトとして使用することができます。
@Repository
public interface PhotoRepository extends JpaRepository<Photo, Integer> {
// PHOTOテーブルがUSER_IDカラムを持つ場合、引数userIdとUSER_IDが一致するレコード取得
Iterator<Photo> findByUserId(int userId);
}
@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);
}