Spring Data JDBCとは?
Spring Data JDBCは、SpringエコシステムでシンプルなRDBアクセスを実現するライブラリです。JPAの複雑さを避けつつ、CRUD操作を簡潔に記述でき、集約ルート設計を推奨することでドメイン駆動設計(DDD)との親和性も高いです。
エンティティ定義
@IdでPKを指定、@Tableでテーブル名をマッピング
@Table("users")
public class User {
@Id
private Long id;
private String name;
private String email;
// getter/setter or Lombok
}
● @Id: 主キー指定(必須)
● @Table: テーブル名マッピング
● @Column: カラム名変更時に使用
Repositoryインターフェース
public interface UserRepository
extends CrudRepository {
List findByEmail(String email);
@Query("SELECT * FROM users WHERE name LIKE :name")
List searchByName(@Param("name") String name);
}
● CrudRepository: 基本CRUD操作を提供
● findBy...: クエリメソッド自動生成
● @Query: SQL直接記述
基本的なCRUD操作
// Create
User user = new User();
user.setName("Alice");
userRepository.save(user);
// Read
Optional found = userRepository.findById(1L);
Iterable all = userRepository.findAll();
// Update
user.setEmail("alice@example.com");
userRepository.save(user);
// Delete
userRepository.deleteById(1L);
userRepository.delete(user);
● save(): INSERT/UPDATEを自動判定
● findById(): 主キーで検索
クエリメソッド命名規則
// 完全一致
List findByName(String name);
// 部分一致
List findByNameContaining(String name);
// 開始・終了一致
List findByNameStartingWith(String prefix);
List findByNameEndingWith(String suffix);
// 比較
List findByAgeGreaterThan(int age);
List findByAgeLessThanEqual(int age);
// AND / OR
List findByNameAndEmail(String name, String email);
List findByNameOrEmail(String name, String email);
// ソート
List findByNameOrderByAgeDesc(String name);
@Queryアノテーションの使い方
基本形(名前付きパラメータ)
@Query("SELECT * FROM users WHERE email = :email")
User findByEmail(@Param("email") String email);
IN句(複数条件)
@Query("SELECT * FROM users WHERE id IN (:ids)")
List findByIds(@Param("ids") List ids);
更新クエリ
@Modifying
@Query("UPDATE users SET email = :email WHERE id = :id")
void updateEmail(@Param("id") Long id, @Param("email") String email);
@Modifying必須
削除クエリ
@Modifying
@Query("DELETE FROM users WHERE email LIKE :pattern")
void deleteByEmailPattern(@Param("pattern") String pattern);
関連エンティティ(集約ルート設計)
Spring Data JDBCでは1:N関係をSetやListで表現し、集約ルート経由でアクセスします
@Table("orders")
public class Order {
@Id
private Long id;
private String orderNumber;
// 1:N関係
private Set items = new HashSet<>();
// getter/setter
}
@Table("order_items")
public class OrderItem {
@Id
private Long id;
private Long orderId; // FK
private String productName;
private int quantity;
// getter/setter
}
● 集約ルート(Order)を保存すると、子(OrderItem)も保存
● 削除時も同様にカスケード
実務で役立つTips
トランザクション
Serviceクラスに@Transactionalを付与して一括処理を保証
作成・更新日時
@CreatedDate、@LastModifiedDateで自動記録(監査機能)
Pageable
PagingAndSortingRepositoryでページング・ソートを簡単実装
SQL検証
logging.level.sql=DEBUGで実行SQLをログ出力
application.properties 設定例
# データソース設定
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=user
spring.datasource.password=pass
# SQL実行ログ出力
logging.level.org.springframework.jdbc.core=DEBUG
# 自動DDL(開発時のみ推奨)
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
本番環境ではspring.sql.init.mode=neverにしてFlywayやLiquibaseでマイグレーション管理を推奨
Spring Data JDBC vs JPA
| 項目 | Spring Data JDBC | JPA/Hibernate |
|---|---|---|
| 複雑さ | シンプル | 複雑(学習コスト高) |
| キャッシュ | なし(明示的) | あり(1次キャッシュ) |
| 遅延ロード | なし(即時ロード) | あり |
| DDD親和性 | 高い(集約ルート) | 中程度 |
| 適用ケース | シンプルなCRUD中心 | 複雑な永続化ロジック |