前回、JPAの基本概念と、Spring Data JPAによってインターフェースとしてRepositoryを定義するだけで、基本的なDB操作メソッド(save、findByIdなど)が自動生成されることを学びました。
この機能のおかげで、私たちはデータを「作成 (Create)」「読み取り (Read)」「更新 (Update)」「削除 (Delete)」するCRUD操作のほとんどで、SQL文を書く必要がなくなりました。
今回は、この自動生成されたCRUDメソッドの使い方と、さらに一歩進んで、独自の検索条件(例: 名前で検索、価格で検索)を追加する方法を学びます。
1. Spring Data JPAによる基本的なCRUD操作
Spring Data JPAの核となる JpaRepository<Entity, 主キー型> インターフェースには、すでに以下のような基本的なCRUDメソッドが定義されています。
| メソッド名 | 概要 | 対応するSQL操作 |
save(entity) | Entityの保存または更新 | INSERT / UPDATE |
findById(id) | 主キー(ID)によるEntityの検索 | SELECT |
findAll() | 全てのEntityの検索 | SELECT |
delete(entity) | Entityの削除 | DELETE |
count() | Entityの総数をカウント | SELECT COUNT |
これらのメソッドは、Service層から ItemRepository のBeanをDIで受け取り、呼び出すだけで利用できます。
【Service層での利用例】
Java
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
// 1. 作成・更新 (Create / Update)
public Item save(Item item) {
// save()は、IDがセットされていなければ新規作成、セットされていれば更新を行う
return itemRepository.save(item);
}
// 2. 読み取り (Read)
public Item findItem(Long itemId) {
// findById()は Optional<Item> を返すため、orElseThrow()などで処理する
return itemRepository.findById(itemId)
.orElseThrow(() -> new RuntimeException("商品が見つかりません: " + itemId));
}
// 3. 削除 (Delete)
public void delete(Item item) {
itemRepository.delete(item);
}
}
2. カスタム検索:メソッド名によるクエリ生成
Spring Data JPAの最も強力な機能は、「特定のルールに従ったメソッド名」をRepositoryインターフェースに記述するだけで、Springが自動的にSQLを生成し、検索処理を実装してくれることです。これをクエリ生成機能と呼びます。
2-1. メソッド命名規則
検索メソッド名は、findBy から始まり、その後に検索したいEntityのフィールド名を結合子(And、Orなど)で繋いで記述します。
| メソッド名 | 意味 |
findBy{フィールド名}(引数) | 指定したフィールドの値に一致するレコードを検索 |
findBy{フィールド名}And{フィールド名2}(引数1, 引数2) | 複数の条件に全て一致するレコードを検索 |
findBy{フィールド名}OrderBy{フィールド名2}Desc() | フィールド2で降順に並び替えて検索 |
【ItemRepository へのカスタム検索の追加】
Item Entityに name(String)と price(int)フィールドがあると仮定します。
Java
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface ItemRepository extends JpaRepository<Item, Long> {
// 1. 名前で検索
// WHERE name = ?
List<Item> findByName(String name);
// 2. 名前の部分一致検索(キーワードを含む)
// WHERE name LIKE %?%
List<Item> findByNameContaining(String keyword);
// 3. 価格帯で検索
// WHERE price BETWEEN ? AND ?
List<Item> findByPriceBetween(int minPrice, int maxPrice);
// 4. 複合条件と並び替え
// WHERE name = ? AND price < ? ORDER BY price DESC
List<Item> findByNameAndPriceLessThanOrderByPriceDesc(String name, int maxPrice);
}
このように、SQL文を一切書かずに、Javaのメソッド名だけで複雑な検索条件を表現できます。Spring Data JPAが、実行時にこのメソッド名に対応する適切なSQLを組み立ててくれます。
3. メソッドの戻り値の型
クエリ生成メソッドの戻り値の型は、検索結果の件数や目的に応じて使い分けます。
| 戻り値の型 | 意味 |
List<Entity> | 複数件の結果(最も一般的) |
Entity | 検索結果が必ず1件であることを想定 |
Optional<Entity> | 検索結果が0件または1件であることを想定(安全性が高い) |
void | 更新・削除などの実行(戻り値がない場合) |
例えば、IDではないがユニークなフィールド(例: ユーザーのメールアドレス)で検索する場合、結果が1件か0件なので Optional<User> を使うのが安全です。
Java
// メールアドレスは重複しない想定
Optional<User> findByEmail(String email);
4. まとめ:生産性を高めるSpring Data JPA
Spring Data JPAのクエリ生成機能は、定型的なDB検索を驚くほど簡単にします。開発者は、SQLの知識よりも**「どのような検索をしたいか」**をJavaのメソッド名として表現することに集中できます。
しかし、メソッド名では表現できないほど複雑な検索や、DB固有の高度なSQL機能を使いたい場合もあります。
✅ 本日のまとめ
- Spring Data JPAの
JpaRepositoryが提供するメソッドで、CRUD操作のほとんどが実現できる。 - クエリ生成機能:
findByから始まる特定の命名規則に従ったメソッド名を定義するだけで、Springが自動でSQLを生成する。 And、Or、Between、Containingなどの結合子をメソッド名に含めることで、複雑な検索条件を設定できる。- 戻り値の型は、検索結果の件数(
List、Optional、Entity)によって使い分ける。
🔔 次回予告
メソッド名によるクエリ生成は便利ですが、あまりに複雑な検索になるとメソッド名が長くなりすぎたり、表現できなかったりします。
次回は、より複雑でDB固有のSQLを使いたい場合に、自分でSQL文を直接書いて検索メソッドを実装する方法(@Query アノテーションの利用)を学びます。
次回:【第22回】Spring Data JPA (2) – @QueryによるカスタムSQLとJPQL にご期待ください!


コメント