カテゴリ: Spring 更新日: 2026/01/19

JavaのSpring Data JPAでデータを保存・更新・削除する方法!初心者向けガイド

Spring のDB登録/更新/削除(Spring Data JPA)
Spring のDB登録/更新/削除(Spring Data JPA)

教材紹介 Spring Boot 学習のおすすめ教材

Spring Bootを使ったWebアプリケーション開発を、 環境構築から実践まで一通り学びたい方には、 定評のある入門書が参考になります。

Spring Boot 3 プログラミング入門をAmazonで見る

※ Amazon広告リンク

先生と生徒の会話形式で理解しよう

生徒

「Spring Data JPAを使ってデータベースにデータを保存する方法を教えてください!」

先生

「もちろんです!Spring Data JPAでは、データの保存や更新、削除が簡単にできます。saveメソッドとdeleteByIdメソッドの使い方を詳しく見ていきましょう。」

生徒

「それは便利ですね!基本的な使い方を知りたいです。」

先生

「では、順を追って具体的に解説しますね。」

1. Spring Data JPAでデータを保存する方法(saveメソッド)

1. Spring Data JPAでデータを保存する方法(saveメソッド)
1. Spring Data JPAでデータを保存する方法(saveメソッド)

まずは「新しいレコードを1件追加する」いちばん基本の流れです。Spring Data JPAでは、エンティティ(ここではUser)を作って Repositorysaveに渡すだけ。IDを自動採番している場合、IDがnullのエンティティは新規追加として保存されます。 実装は「リポジトリを用意 → コントローラで受け取った値を詰める → save呼び出し」の3ステップで完了します。


import org.springframework.data.jpa.repository.JpaRepository;

// Userエンティティ用のリポジトリ。実装はSpringが自動生成します。
public interface UserRepository extends JpaRepository<User, Integer> {
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserController {

    @Autowired
    private UserRepository userRepository;

    // 例: /users/create?username=taro&amp;email=taro@example.com
    @GetMapping("/users/create")
    public String createUser(@RequestParam String username,
                             @RequestParam String email,
                             Model model) {
        // 1) 入力値からエンティティを作成
        User user = new User();
        user.setUsername(username);
        user.setEmail(email);

        // 2) saveで保存(IDがnullなのでINSERTされる)
        User saved = userRepository.save(user);

        // 3) 結果を画面に渡す(採番されたIDも取得できる)
        model.addAttribute("message", "User created successfully (id=" + saved.getId() + ")");
        return "result";
    }
}

実行の感触をつかむコツとして、まずはブラウザでURLに名前とメールを付けて叩き、保存後に返ってくるIDを画面で確認してみてください。saveは保存した実体を返すので、そのままメッセージに埋め込めます。未入力だと空文字のまま登録される点は注意(最初は動かすことを優先し、入力チェックはあとから段階的に足すのがおすすめ)。また今回は手早く試すためにGETを使っていますが、フォーム投稿としてはPOSTを使うのが一般的です。まずは小さく通して仕組みを理解し、必要になったらバリデーションや画面設計を整える、という順番で進めると学習がスムーズです。

2. Spring Data JPAでデータを更新する方法(saveメソッド)

2. Spring Data JPAでデータを更新する方法(saveメソッド)
2. Spring Data JPAでデータを更新する方法(saveメソッド)

既存のデータを更新する場合もsaveメソッドを使います。更新したいエンティティのIDを指定し、必要なプロパティを更新してからsaveメソッドで保存します。例えば、ユーザーの情報を更新する場合、次のようにします。


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users/update")
    public String updateUser(@RequestParam Integer id, @RequestParam String username, @RequestParam String email, Model model) {
        User user = userRepository.findById(id).get();
        user.setUsername(username);
        user.setEmail(email);
        userRepository.save(user);
        model.addAttribute("message", "User updated successfully");
        return "result";
    }
}

このコードでは、/users/updateエンドポイントにid, usernameおよびemailパラメータを渡すことで指定したIDのユーザー情報が更新されます。

3. Spring Data JPAでデータを削除する方法(deleteByIdメソッド)

3. Spring Data JPAでデータを削除する方法(deleteByIdメソッド)
3. Spring Data JPAでデータを削除する方法(deleteByIdメソッド)

データを削除するには、deleteByIdメソッドを使用します。このメソッドは、指定したIDのデータをデータベースから削除します。以下のコード例では、指定したIDのユーザーを削除します。


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users/delete")
    public String deleteUser(@RequestParam Integer id, Model model) {
        userRepository.deleteById(id);
        model.addAttribute("message", "User deleted successfully");
        return "result";
    }
}

このコードでは、/users/deleteエンドポイントにidパラメータを渡すことで、該当のIDのユーザーが削除されます。

Spring FrameworkやThymeleafを使った Webアプリ開発の全体像をやさしく理解したい人には、 この入門書が定番です。

Spring Framework超入門をAmazonで見る

※ Amazon広告リンク

4. saveの挙動と「新規/更新」の判定・まとめて保存(saveAll/saveAndFlush)

4. saveの挙動と「新規/更新」の判定・まとめて保存(saveAll/saveAndFlush)
4. saveの挙動と「新規/更新」の判定・まとめて保存(saveAll/saveAndFlush)

Spring Data JPAのsaveアップサート(insert or update)として動作します。通常、@GeneratedValueでIDを自動採番している場合は、IDが未設定(null)なら新規保存、既存IDが紐づくなら更新になります。大量データはsaveAllでまとめて登録し、即時にDBへ反映したい場面ではsaveAndFlushが便利です(大量処理ではバッチ設定も検討)。


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;
import java.util.Arrays;

@Controller
public class UserBulkController {

    @Autowired
    private UserRepository userRepository;

    // まとめて新規保存(アップサート)
    @GetMapping("/users/bulkCreate")
    public String bulkCreate(Model model) {
        List<User> users = Arrays.asList(
            new User(null, "taro", "taro@example.com"),
            new User(null, "hanako", "hanako@example.com")
        );
        userRepository.saveAll(users);
        model.addAttribute("message", "Users created (bulk)");
        return "result";
    }
}
  

補足:更新は「永続化コンテキスト」に管理されたエンティティなら、@Transactional内でプロパティを書き換えるだけでダーティチェッキングにより自動反映されます(明示save不要)。


import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserWriteService {

    private final UserRepository repo;
    public UserWriteService(UserRepository repo) { this.repo = repo; }

    @Transactional
    public void rename(Integer id, String newName) {
        User u = repo.findById(id).orElseThrow(() -> new IllegalArgumentException("not found"));
        u.setUsername(newName); // トランザクション終了時に自動UPDATE
    }
}
  

5. 削除のベストプラクティス(deleteById/関連のカスケード/論理削除)

5. 削除のベストプラクティス(deleteById/関連のカスケード/論理削除)
5. 削除のベストプラクティス(deleteById/関連のカスケード/論理削除)

deleteByIdは最もシンプルな物理削除です。ただし親子関係(@OneToManyなど)がある場合、外部キー制約でエラーになりがちなので、cascade = CascadeType.REMOVEorphanRemoval = trueを設計段階で検討します。履歴保持が必要なら論理削除(ソフトデリート)のフラグを導入し、検索時は未削除のみを返すクエリメソッドを用意します。


import jakarta.persistence.*;
import java.util.List;

@Entity
public class User {
    @Id @GeneratedValue
    private Integer id;
    private String username;
    private String email;
    private boolean deleted = false; // 論理削除フラグ

    @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE, orphanRemoval = true)
    private List<Post> posts;

    // getter/setter 省略
}

public interface UserRepository extends JpaRepository<User, Integer> {
    // 論理削除対応の検索
    List<User> findByDeletedFalse();
}
  

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserDeleteController {

    @Autowired
    private UserRepository userRepository;

    // 物理削除
    @GetMapping("/users/remove")
    public String remove(@RequestParam Integer id, Model model) {
        userRepository.deleteById(id); // 存在しないIDは例外になる場合あり
        model.addAttribute("message", "User deleted");
        return "result";
    }

    // 論理削除
    @GetMapping("/users/softDelete")
    public String softDelete(@RequestParam Integer id, Model model) {
        User u = userRepository.findById(id).orElse(null);
        if (u == null) {
            model.addAttribute("message", "User not found");
            return "result";
        }
        u.setDeleted(true); // フラグのみ更新
        userRepository.save(u);
        model.addAttribute("message", "User soft-deleted");
        return "result";
    }
}
  

SEO・UXの観点では、「削除後のリダイレクト先」や「確認ダイアログ」も重要です。誤操作防止のため、確認画面→実行の二段階にすると安心です(実運用ではHTTPメソッドもDELETE/POSTに分離)。

6. 保存・更新・削除で起きやすい例外と対策(@Transactional/一意制約/同時更新)

6. 保存・更新・削除で起きやすい例外と対策(@Transactional/一意制約/同時更新)
6. 保存・更新・削除で起きやすい例外と対策(@Transactional/一意制約/同時更新)

CRUD実装では例外処理とトランザクション境界が品質を左右します。代表的には、DataIntegrityViolationException(一意制約やFK制約違反)、EmptyResultDataAccessException(存在しないIDをdeleteById)など。@Transactionalで一連の保存・更新・削除をまとめ、発生時はロールバックしてユーザーに分かりやすいメッセージを返します。


import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SafeCrudController {

    private final UserWriteService service;

    public SafeCrudController(UserWriteService service) { this.service = service; }

    @GetMapping("/users/safeRename")
    public String safeRename(Integer id, String username, Model model) {
        try {
            service.rename(id, username);
            model.addAttribute("message", "User updated (tx committed)");
        } catch (IllegalArgumentException e) {
            model.addAttribute("message", "User not found");
        } catch (DataIntegrityViolationException e) {
            model.addAttribute("message", "Constraint violation");
        }
        return "result";
    }

    @GetMapping("/users/safeDelete")
    public String safeDelete(Integer id, Model model) {
        try {
            service.delete(id);
            model.addAttribute("message", "User deleted");
        } catch (EmptyResultDataAccessException e) {
            model.addAttribute("message", "User already removed or not found");
        }
        return "result";
    }
}
  

同時更新の競合には楽観的ロック@Version)が有効です。更新時にバージョン不一致を検知して例外を投げ、ユーザーに「他で更新されました」と再入力を促します。これにより「更新の取りこぼし」を防ぎ、タイトル通りの保存・更新・削除を堅牢に実装できます。

まとめ

まとめ
まとめ

この記事では、Spring Data JPAを使ってデータベースにデータを保存、更新、削除する方法について解説しました。saveメソッドとdeleteByIdメソッドを使用することで、初心者でも簡単にCRUD操作を実現できます。Spring Data JPAは、SQLを直接書かなくてもデータ操作ができる点で非常に便利であり、開発効率を大幅に向上させます。

特に、saveメソッドは新規データの追加だけでなく、既存データの更新にも利用できるため、柔軟性に優れています。一方で、deleteByIdメソッドを使えば、特定のIDのデータを簡単に削除することが可能です。これにより、エンティティの管理が非常にシンプルになります。

また、Spring BootのControllerクラスを使用してエンドポイントを作成し、データベース操作をHTTPリクエスト経由で行う方法も学びました。これにより、ウェブアプリケーションのバックエンドでデータ操作を簡単に実装できます。以下に、今回の記事で紹介した主要なコード例をまとめました。


<!-- Userエンティティ -->
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class User {
    @Id
    private Integer id;
    private String username;
    private String email;

    // Getter, Setter
}

<!-- UserRepositoryインターフェース -->
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Integer> {
}

<!-- UserControllerクラス -->
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users/create")
    public String createUser(@RequestParam String username, @RequestParam String email, Model model) {
        User user = new User();
        user.setUsername(username);
        user.setEmail(email);
        userRepository.save(user);
        model.addAttribute("message", "User created successfully");
        return "result";
    }

    @GetMapping("/users/update")
    public String updateUser(@RequestParam Integer id, @RequestParam String username, @RequestParam String email, Model model) {
        User user = userRepository.findById(id).get();
        user.setUsername(username);
        user.setEmail(email);
        userRepository.save(user);
        model.addAttribute("message", "User updated successfully");
        return "result";
    }

    @GetMapping("/users/delete")
    public String deleteUser(@RequestParam Integer id, Model model) {
        userRepository.deleteById(id);
        model.addAttribute("message", "User deleted successfully");
        return "result";
    }
}

これらのコードを参考にすることで、Spring Data JPAを活用したCRUD操作の基本をマスターすることができます。また、HTTPリクエストと連携することで、ウェブアプリケーションに必要なデータ操作機能を簡単に実現可能です。ぜひ、実際のプロジェクトで活用してみてください。

先生と生徒の振り返り会話

生徒

「Spring Data JPAのsaveメソッドって、データの保存だけでなく、更新にも使えるんですね!便利です。」

先生

「その通りです。新規追加も更新も同じメソッドで対応できるのは、Spring Data JPAの強みです。ただし、IDの指定を間違えないように気をつけましょう。」

生徒

「データ削除も簡単ですね。deleteByIdを使うだけなんて驚きました!」

先生

「そうですね。ただし、削除する前に、本当に必要な操作かを確認する仕組みを追加すると、さらに安全になります。」

生徒

「これなら、簡単なCRUDアプリケーションをすぐに作れそうです。次は、もっと複雑な機能に挑戦したいです!」

先生

「いいですね。次回はリレーショナルデータベースの操作や、カスタムクエリについて詳しく学びましょう!」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Spring Data JPAのsaveメソッドは新規作成と更新のどちらに使えますか?

saveメソッドは、新しいデータの作成と既存データの更新の両方に使用できます。新規データの場合はIDを設定せずに保存し、更新の場合は対象データのIDを指定して保存します。

deleteByIdメソッドを使うとき、対象のデータが存在しない場合はどうなりますか?

deleteByIdメソッドを実行すると、対象データが存在しない場合に例外がスローされます。実行前に存在を確認する方法を追加すると安全です。

findByIdメソッドでデータが見つからない場合はどう処理しますか?

findByIdメソッドはOptionalを返すため、データが見つからない場合はisPresentでチェックしたり、orElseThrowを使ってカスタム例外をスローできます。

Spring Bootプロジェクトでデータベース接続情報を設定するにはどうすればいいですか?

データベース接続情報はapplication.propertiesまたはapplication.ymlに記載します。例えば、MySQLを使う場合はURL、ユーザー名、パスワードを設定します。

データベースの初期データを登録するにはどうすればいいですか?

初期データはsrc/main/resourcesディレクトリにdata.sqlファイルを配置することで、自動的に登録されます。テーブル作成はschema.sqlファイルを使用します。

saveメソッドで更新を行う際、他のフィールドの値を変更せずに維持するにはどうすればいいですか?

findByIdでエンティティを取得し、必要なフィールドのみを変更してからsaveメソッドを呼び出します。これにより、他のフィールドの値は維持されます。

Spring Data JPAで複数のエンティティを一括削除する方法はありますか?

リポジトリのdeleteAllメソッドを使用すると、全データを一括削除できます。また、deleteAllInBatchを使えば、バッチ処理で効率的に削除可能です。

saveメソッドを使った操作で同時実行制御を行うにはどうすればいいですか?

@Transactionalアノテーションを使用してトランザクション管理を行うことで、同時実行制御を適用できます。また、必要に応じてロック機構を追加することも可能です。

Spring Data JPAでのエラーハンドリングのベストプラクティスは何ですか?

例外をキャッチして適切なレスポンスを返すために、@ControllerAdviceを使用してカスタム例外ハンドラを作成するのがおすすめです。

Spring Data JPAでカスタムクエリを作成するにはどうすればいいですか?

@Queryアノテーションをリポジトリメソッドに追加することで、カスタムSQLを記述できます。JPQLやネイティブクエリもサポートされています。
カテゴリの一覧へ
新着記事
JSPとは何か?初心者向けにできること・仕組み・特徴をやさしく解説
Spring BootのMultipartFile入門:ファイルアップロード・ダウンロードの実装方法と制限設定
JavaのIndexOutOfBoundsExceptionを完全ガイド!初心者でも理解できる例外処理と回避方法
スッキリわかるJava入門 第4版|独学でもレッスンでも学べる完全ガイド
人気記事
No.1
Java&Spring記事人気No1
Spring BootとJavaの互換性一覧!3.5/3.4/3.3はJava 21・17に対応してる?
No.2
Java&Spring記事人気No2
Springの@Serviceアノテーションの使い方を徹底解説!初心者でもわかるSpring フレームワーク入門
No.3
Java&Spring記事人気No3
Spring Data JPA入門!findAll()やfindBy**()の使い方などデータベース操作の基礎を学ぶ
No.4
Java&Spring記事人気No4
Spring BootのJakarta移行ガイド!初心者向けjavax→jakarta変更ポイント徹底解説
No.5
Java&Spring記事人気No5
Thymeleafのth:classappend属性の使い方を完全ガイド!初心者でもわかる動的クラス追加
No.6
Java&Spring記事人気No6
Thymeleaf(タイムリーフ)入門!初心者でもわかるSpring Bootとテンプレートエンジンの使い方
No.7
Java&Spring記事人気No7
Springの@Repositoryアノテーションの使い方を徹底解説!初心者でもわかるSpringフレームワークのデータアクセス
No.8
Java&Spring記事人気No8
SpringのPageableとSortでページング一覧APIを最短実装!初心者向け完全ガイド

💻 作業効率アップに

長時間のコーディングでも疲れにくい♪ 静音ワイヤレスマウス

Logicool Signature M750 を見る

※ Amazon広告リンク