SpringのdeleteByIdで簡単データ削除!初心者にもわかる使い方ガイド
新人
「Springでデータを削除したいんですけど、簡単にできる方法ってありますか?」
先輩
「あるよ。JpaRepositoryが提供しているdeleteById()メソッドを使えば、IDを指定するだけでデータを簡単に削除できるんだ。」
新人
「えっ、SQL書かなくてもいいんですか?そんな簡単に削除できるなんてびっくりです!」
先輩
「うん。Spring Data JPAの便利なところの一つだね。deleteById()は、Spring deleteById 使い方としてもよく検索されるくらい、初心者に人気なんだよ。詳しく説明していくね。」
1. deleteByIdとは何か
deleteById()は、Spring FrameworkのJpaRepositoryインターフェースに標準で用意されているメソッドです。このメソッドを使うと、指定したID(主キー)に該当するエンティティを、データベースから完全に削除することができます。
この削除操作はSQLを直接書かずに、メソッド呼び出しだけで行えるため、初心者にも非常に使いやすく、実装ミスを減らすことができます。
例えば、次のように記述するだけで、データベース内のユーザー情報を削除することができます。
userRepository.deleteById(1L);
この1行で、「IDが1のユーザーを削除する」というSQL(DELETE FROM users WHERE id = 1)と同じ処理が自動的に実行されます。これがエンティティ 削除 方法としてSpringが優れている理由の一つです。
また、deleteById()は戻り値を返さないため、削除の結果を確認したい場合は、事前にfindById()で存在確認をするのが一般的です。これについては中盤以降で詳しく紹介します。
2. データベースにあるデータを削除するとはどういうことか
アプリケーションで「データを削除する」とは、単に画面から見えなくすることではなく、データベースに保存されている情報を物理的に削除するという意味です。つまり、削除後はそのデータは二度と取得できず、完全に消えてしまいます。
たとえば、ユーザー管理画面で「削除」ボタンを押すと、対応するIDのユーザーデータがデータベースから消去されます。この操作は、画面に表示されなくなるだけでなく、findAll()やfindById()でも取得できなくなるということです。
そのため、削除処理を行う際には、以下のような確認や対応が必要です。
- 本当に削除してよいデータか事前確認する(ユーザーの確認ダイアログなど)
- 削除後の画面遷移やメッセージ表示を丁寧に設計する
- 削除前にログを残す、または論理削除(フラグで管理)を検討する
特に初心者は、データベースからデータを削除することの重みを理解し、deleteById()がもたらす影響を把握したうえで使用することが大切です。
また、deleteById()によって削除されるのは、「エンティティ」に対応するテーブルの1行です。複数のテーブルにリレーション(外部キー制約)がある場合は、削除時に例外が発生することもあるため、そうした点も意識しておきましょう。
このように、Spring Data JPAを使ったdeleteById()は、簡単であるがゆえに、仕組みをしっかり理解して安全に使うことが重要です。
3. deleteByIdの基本的な使い方を確認しよう
それでは、実際にdeleteById()を使ってデータを削除する具体的な方法を確認しましょう。今回は、ユーザー情報を管理するUserエンティティと、それに対応するUserRepositoryを使って、JpaRepository delete 方法を紹介します。
まずは、エンティティクラスであるUserを定義します。
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getterとsetter
}
次に、JpaRepositoryを継承したUserRepositoryを作成します。
public interface UserRepository extends JpaRepository<User, Long> {
}
そして、@Controllerクラスを使って、削除処理を実装します。Pleiades環境でGradleプロジェクトを作成し、このような構成にすることで、Spring deleteById 使い方を簡単に実装できます。
@Controller
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/delete")
public String deleteUser(@RequestParam("id") Long id) {
userRepository.deleteById(id);
return "redirect:/user/list";
}
}
このように、URLに?id=1のようにIDを渡すことで、対象のユーザーを削除できます。特に難しい設定や記述は必要ありません。
4. 存在しないIDを指定したときの挙動に注意
deleteById()は非常に便利ですが、存在しないIDを指定したときにどうなるのか、という点は非常に重要です。たとえば、ID「1000」のユーザーが存在しない状態で、deleteById(1000L)を実行すると、どうなるでしょうか?
このような場合、Spring delete エラーとして次のような例外が発生します。
org.springframework.dao.EmptyResultDataAccessException: No class com.example.User entity with id 1000 exists!
このエラーは、削除対象のデータが存在しないときに発生するものです。初心者が最初につまずきやすいポイントの一つなので注意が必要です。
この問題を回避するには、削除処理を実行する前に、findById()でデータが存在するかどうかを確認するのが良い方法です。次のセクションで詳しく説明します。
5. findByIdとdeleteByIdを組み合わせて安全に削除しよう
deleteById()を安全に使うためには、事前にfindById()で対象のデータが存在するかを確認することが重要です。これにより、存在しないID 削除によるエラーを未然に防ぐことができます。
下記は、findById()とdeleteById()を併用した例です。
@GetMapping("/deleteSafe")
public String deleteSafe(@RequestParam("id") Long id, Model model) {
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isPresent()) {
userRepository.deleteById(id);
return "redirect:/user/list";
} else {
model.addAttribute("message", "指定されたユーザーは存在しません。");
return "error";
}
}
この方法では、データが存在するときだけ削除処理を行い、存在しない場合はエラーメッセージを表示することができます。JpaRepository delete 注意点として、非常に効果的な対策です。
また、エラーメッセージの表示やログ出力を追加することで、ユーザーにも開発者にも分かりやすいアプリケーションを作成することができます。
このように、deleteById()は便利な反面、安易に使うと問題が起こることもあるため、findById()を組み合わせて、安全かつ確実に処理を行うことが推奨されます。
6. フォーム画面から削除処理を行う方法(ThymeleafとControllerの連携)
ここからは、Spring 削除画面 作り方の実例として、Thymeleafを使った削除画面を作成していきましょう。ThymeleafはSpringと非常に相性が良く、フォームとの連携も簡単にできます。
まず、削除対象の一覧ページに削除ボタンを表示するためのテンプレートを作成します。
<table>
<tr th:each="user : ${userList}">
<td th:text="${user.name}"></td>
<td th:text="${user.email}"></td>
<td>
<form th:action="@{/user/delete}" method="post">
<input type="hidden" name="id" th:value="${user.id}" />
<button type="submit">削除</button>
</form>
</td>
</tr>
</table>
このテンプレートでは、各ユーザーごとに削除ボタンを表示し、押されたときに/user/deleteへPOSTリクエストを送るようになっています。
次に、コントローラ側でPOSTリクエストを受け取って削除処理を行います。
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserRepository userRepository;
@PostMapping("/delete")
public String deleteByForm(@RequestParam("id") Long id, RedirectAttributes redirectAttributes) {
Optional<User> userOpt = userRepository.findById(id);
if (userOpt.isPresent()) {
userRepository.deleteById(id);
redirectAttributes.addFlashAttribute("message", "削除しました。");
} else {
redirectAttributes.addFlashAttribute("error", "ユーザーが存在しません。");
}
return "redirect:/user/list";
}
@GetMapping("/list")
public String showList(Model model) {
List<User> userList = userRepository.findAll();
model.addAttribute("userList", userList);
return "user/list";
}
}
このようにすれば、Thymeleaf delete 実装例として、削除画面とコントローラを連携させた実装が完成します。初心者の方でも、PleiadesとGradleを使えば簡単に動作させることができます。
7. 削除後のリダイレクトや確認メッセージの表示方法
削除処理を行った後に、「削除が成功した」ことをユーザーに伝えることはとても大切です。SpringではRedirectAttributesを使って、削除後のリダイレクト先にメッセージを渡すことができます。
先ほどのコントローラ内でも使用していますが、ここでもう一度ポイントをおさらいします。
redirectAttributes.addFlashAttribute("message", "削除しました。");
このようにすると、次の画面でmessage属性が一度だけ利用可能になります。
Thymeleafテンプレート側では、以下のように表示します。
<div th:if="${message}">
<p th:text="${message}"></p>
</div>
<div th:if="${error}">
<p th:text="${error}"></p>
</div>
これで、削除処理が成功した場合や失敗した場合に、それぞれのメッセージが表示されるようになります。こうしたフィードバックは、ユーザーの安心感にもつながるため、初心者のうちから実装しておくことをおすすめします。
8. deleteAllとの違いや、今後学ぶべき削除関連の知識
今回は、deleteById()を中心に、削除処理の基本からエラーハンドリング、フォームとの連携まで、初心者向けに丁寧に解説してきました。
ここで最後に、deleteAll 違いについても少し触れておきましょう。
deleteById()は、IDを指定して特定の1件のデータを削除するのに対し、deleteAll()はテーブル内の全件を一括削除するメソッドです。
userRepository.deleteAll();
このメソッドを使うと、ユーザー情報がすべて削除されるため、開発や検証環境では便利ですが、本番環境では非常に危険です。間違えて実行してしまうと、全データが消えてしまうリスクがあるため注意しましょう。
また、今後は以下のような知識も学んでいくと、より実践的なアプリケーション開発ができるようになります。
- 論理削除(削除フラグを使った非表示処理)
- 削除前の確認ダイアログ表示(JavaScriptなど)
- 関連エンティティのカスケード削除設定
- 例外発生時の共通エラーハンドリング(@ControllerAdviceなど)
deleteById()は初心者にも分かりやすく、扱いやすい削除メソッドです。しかし、その便利さの裏には、データを完全に消してしまうというリスクもあります。今回の記事を通して、ただ書くだけでなく、「安全に扱う」ことの大切さも感じていただけたら幸いです。
今後は、今回紹介したdeleteById()やdeleteAll()に加え、論理削除などの応用的な削除処理も積極的に学んでいきましょう。