本文へスキップ
BecomeCoder

Spring / Spring Bootコース · 第5章 データアクセス ― Spring Data JPA · レッスン18

JpaRepositoryでCRUD

ローカル実施

導入

@Entity でテーブルとクラスが結びついたら、次は「保存する」「探す」「削除する」といった操作をどう書くかです。SQLを自分で書かずに、これらをどう実現するのでしょうか。

説明

Spring Data JPAでは、インターフェースを1つ定義するだけCRUD(Create/Read/Update/Delete)操作が手に入ります。

public interface UserRepository extends JpaRepository<User, Long> {
    // 中身は空でよい! Long は主キーの型
}

驚くべきことに、UserRepository には実装クラスを一切書いていません。Spring Data JPAが起動時にこのインターフェースを見つけ、実装クラスを自動生成(プロキシとして動的に作成) し、Beanとして登録します。

graph TD
  Iface["interface UserRepository<br/>extends JpaRepository&lt;User, Long&gt;"] -->|起動時に自動生成| Proxy["実装クラス(プロキシ)<br/>save/findById/findAll等を実装済み"]
  Proxy -->|Beanとして登録| Ctx["ApplicationContext"]

JpaRepository継承した時点で、次のようなメソッドがすでに使えます。

@Service
class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User create(User user) {
        return userRepository.save(user); // INSERT または UPDATE
    }

    public Optional<User> findOne(Long id) {
        return userRepository.findById(id); // SELECT ... WHERE id = ?
    }

    public List<User> findAll() {
        return userRepository.findAll(); // SELECT * FROM users
    }

    public void remove(Long id) {
        userRepository.deleteById(id); // DELETE ... WHERE id = ?
    }
}
メソッドやること
save(entity)新規保存、または既存データの更新
findById(id)主キーで1件取得(Optional で返る=見つからない可能性がある)
findAll()全件取得
deleteById(id)主キーで1件削除

findById の戻り値が User ではなく Optional<User> になっている点に注目してください。「見つからないかもしれない」ということが型で表現されており、呼び出し側は null チェックの代わりに Optional の機能(orElseThrow など)を使って安全に扱えます。

やってみよう

「メールアドレスで既存ユーザーを検索して見つからなければ登録する」という処理を、UserRepositoryfindById 以外のメソッドが必要になりそうだと気づけましたか。次のレッスンでその方法を扱います。