Spring Data JDBCは、JDBCを用いたシンプルかつ効果的なデータベース操作を提供するフレームワークです。
ここでは概要を省き、Spring Data JDBCのクエリメソッドの具体的な使用例と実用的なケースについて解説します。
1. 前提条件:サンプルDBテーブルとエンティティ定義
今回の例では、Productテーブルを対象にします。このテーブルには以下のカラムがあります。
id | name | age | region | |
---|---|---|---|---|
1 | 田中 太郎 | 25 | 東京 | taro.tanaka@example.com |
2 | 鈴木 一郎 | 32 | 神奈川 | ichiro.suzuki@example.com |
3 | 佐藤 花子 | 28 | 大阪 | hanako.sato@example.com |
4 | 山本 健二 | 45 | 福岡 | kenji.yamamoto@example.com |
5 | 高橋 裕子 | 38 | 愛知 | yuko.takahashi@example.com |
エンティティ定義
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("user")
public class User {
@Id
private Long id;
private String name;
private Integer age;
private String region;
private String email;
// Getters, Setters, Constructors are omitted for brevity
}
2. 基本のCRUD操作
CrudRepositoryを使用することで、基本的なCRUD操作が簡単に実装できます。
CrudRepositoryインターフェースの定義
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
}
使用例
// 1件取得
Optional<User> user = userRepository.findById(1L);
// 全件取得
Iterable<User> users = userRepository.findAll();
// 新規保存
User newUser = new User(null, "Setsuko Nakamura", 29, "Chiba", "setsuko.nakamura@example.com");
userRepository.save(newUser);
// 削除
userRepository.deleteById(5L);
3. クエリメソッドの命名規則と自動クエリ生成
Spring Data JDBCでは、クエリメソッドの命名規則に基づき、SQLが自動生成されます。
「findBy」で始まるメソッド名に続けてカラム名や条件を含めることで、クエリが生成されます。
特定の地域に基づくユーザー検索
List<User> findByRegion(String region);
使用例
List<User> usersInTokyo = userRepository.findByRegion("Tokyo")
結果
「東京」に住むユーザー(例:田中 太郎)の情報が返されます。
4. @QueryアノテーションによるカスタムSQL
複雑なクエリが必要な場合、@QueryアノテーションでSQLを直接指定できます。
import org.springframework.data.jdbc.repository.query.Query;
@Query("SELECT * FROM user WHERE age > :age")
List<User> findUsersByAgeGreaterThan(Integer age);
使用例
List<User> adults = userRepository.findUsersByAgeGreaterThan(30);
結果
年齢が30以上のユーザー(鈴木 一郎、山本 健二、高橋 裕子)が返されます。
5. 複数条件でのクエリメソッド
複数の条件を組み合わせたクエリメソッドも利用可能です。
地域と年齢の条件でフィルタリング
List<User> findByRegionAndAgeGreaterThan(String region, Integer age);
使用例
List<User> olderUsersInKanagawa = userRepository.findByRegionAndAgeGreaterThan("神奈川", 30);
結果
神奈川に住む年齢30以上のユーザー(鈴木 一郎)が返されます。
6. 動的クエリの実装
@Queryアノテーションを使い、条件を動的に切り替えられるクエリも実装可能です。
例えば、以下のように地域や年齢の条件を任意に設定します。
可変条件での検索
@Query("SELECT * FROM user WHERE (:region IS NULL OR region = :region) AND (:age IS NULL OR age > :age)")
List<User> findUsersByDynamicCriteria(Optional<String> region, Optional<Integer> age);
使用例
List<User> users = userRepository.findUsersByDynamicCriteria(Optional.of("大阪"), Optional.empty());
結果
「大阪」に住むユーザー(佐藤 花子)が返されます。
7. 集約関数を使用したクエリメソッド
@Queryアノテーションを使用して、データの集計も行えます。
地域ごとの平均年齢を取得
@Query("SELECT AVG(age) FROM user WHERE region = :region")
Double findAverageAgeByRegion(String region);
使用例
Double averageAgeInTokyo = userRepository.findAverageAgeByRegion("東京");
結果
「東京」に住むユーザーの平均年齢が返されます(例では25)。
8. プロジェクションを使った部分的なデータ取得
特定のフィールドのみ取得したい場合は、プロジェクションインターフェースを使用します。
プロジェクションインターフェースの定義
public interface UserSummary {
String getName();
Integer getAge();
}
List<UserSummary> findByRegion(String region);
使用例
// 使用例
List<UserSummary> summaries = userRepository.findByRegion("福岡");
結果
福岡に住むユーザー(山本 健二)の「name」と「age」のみが返されます。
9. ページングとソート機能の活用
PagingAndSortingRepositoryを使用すると、ページングやソートを含むデータ取得が可能です。
インターフェースの定義
import org.springframework.data.repository.PagingAndSortingRepository;
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
}
使用例
Pageable pageable = PageRequest.of(0, 10, Sort.by("age").descending());
Page<User> usersPage = userRepository.findAll(pageable);
結果
年齢が高い順にユーザーがページングされて返されます。
10. 関連エンティティの取得とネストされたクエリ
複数のエンティティが関連している場合、Spring Data JDBCでは親エンティティと関連エンティティを同時に取得できます。
例えば、Userエンティティが「Order」エンティティを持つ場合を考えます。
Orderエンティティの定義
@Table("order")
public class Order {
@Id
private Long id;
private Long userId;
private String productName;
private Integer quantity;
// Getters and Setters are omitted
}
Userエンティティに関連を持たせる
@Table("user")
public class User {
@Id
private Long id;
private String name;
private Integer age;
private String region;
private String email;
@MappedCollection(idColumn = "user_id")
private Set<Order> orders;
}
リポジトリの定義
public interface UserRepository extends CrudRepository<User, Long> {
}
使用例
Optional<User> user = userRepository.findById(1L);
結果
Userエンティティに関連するOrderのセットも含めて、ユーザー情報が取得されます。
まとめ
Spring Data JDBCのクエリメソッドは、シンプルなSQLの自動生成から複雑なクエリまで対応可能で、柔軟なデータアクセスが実現します。
プロジェクション、ページング、カスタムSQL、動的クエリを組み合わせて、実用的かつ効率的なデータベース操作が可能です。
コメント