概要
CRUD(クラッド)とは、データベース管理システム(DBMS)の4つの基本機能「Create(作成)」「Read(参照)」「Update(更新)」「Delete(削除)」を指します。
Webアプリ開発を学ぶうえで、学習中の言語・フレームワークでCRUDを一通り作れるかどうかは1つのターニングポイントになります。
今まで学習した内容を駆使して、各種機能を実装しましょう!
また、今までの単元も見返すことはもちろん、検索してネット上の他人のコードも調べて参考にすると良いでしょう。
・テーマや画面の見た目は自由に決めてください。CSSの装飾は任意です。
・登録するデータは、様々なデータ型を用意してください(文字列、日付など)
・1つのデータに対する詳細情報のテーブルも用意し、リレーションを用いた詳細画面も作成します。(多対多)
《 テーブル作成例 》
・モンスターテーブル ・中間テーブル ・シリーズマスタテーブル

作成するテーブルの内容に自信がない場合は講師に確認依頼しましょう。
進捗の目安
以下の表を基準に、8営業日以内に終えられるよう作業を進めましょう。
基本的には下表の左上から順に作業を進めてください。
| 準備段階 | ||
| テーブル作成 | 0.5日 | |
| 一覧ページ | ||
| 一覧表示 | 0.5日 | |
| 新規作成 | 0.5日 | |
| 編集 | 0.5日 | |
| 削除 | 0.5日 | |
| 検索 | 0.5日 |
| 詳細ページ | ||
| 詳細表示 | 0.5日 | |
| 新規作成 | 1日 | |
| 編集 | 1日 | |
| 削除 | 0.5日 | |
| レビュー後 | ||
| 修正作業 | 1日 |
実装する機能
★共通事項(全機能共通)
<登録・更新・削除 系>
・処理の完了後、一覧画面にリダイレクトし「登録が完了しました。」などのメッセージが表示されるよう実装してください。
<登録・更新・検索 系>
・バリデーションを設定し、バリデーションメッセージも表示してください
(登録・更新系:文字数、ユニーク(重複不可)、数値の範囲など)
・バリデーションエラーが出た際は、古い入力値を保持するようにしましょう。
一覧画面(一覧画面表示機能)
メインのテーブルのデータを一覧表示する画面です。検索のフォームを上部に設置します。
一覧表示のViewは、検索結果を表示する際にも使用します。

登録・更新画面(画面表示機能、登録・更新機能)
登録、更新画面を作成します。
一覧画面の「新規作成」をクリックすると新規登録画面を表示、各行の「編集」をクリックすると該当データの編集画面を表示します。
新規登録と編集のViewは同じhtmlを共用する形で作成できますが、ここでは別々で作成しても構いません。
データ更新の場合は、テーブルに登録されている編集対象のデータを表示しましょう。
各画面の「登録」をクリックすると登録または更新処理が実行されます。
・新規登録の場合

・データ更新の場合

削除機能
一覧画面の削除ボタンを押すと、対象のデータがDBから削除され、一覧に表示されなくなるよう実装します。
検索機能
一覧ページにて、検索機能を実装します。
検索条件は、キーワード、数値の範囲検索などのAND検索とします。
数値の範囲検索であれば上下関係が正しいかのチェックも実装しましょう。(3~1といった検索は不正でNG 等)
検索のバリデーションでは、未入力は許容するので@NotNullなどは使用する必要はありません。
該当データがない場合、下図のようにその旨が表示されるようにしましょう。

詳細画面(詳細画面表示機能)
一覧画面の各行のIDをリンクにし、詳細画面に飛ぶようにします。
対象のIDの画面を設定するには、URLのパラメータにIDを渡してあげます。
詳細画面では
上部に主テーブルのデータ、
下部にはリレーションした相手側テーブルと中間テーブルのデータ を表示します。

詳細項目の新規作成・編集画面(画面表示機能、登録・更新機能)
対象のIDに紐づく詳細データを登録する画面・機能を作成します。
データの登録・更新としては、中間テーブルのデータを更新します。中間テーブルについては「リレーション」を参照してください。
セレクトボックスには相手側テーブル(この例だとシリーズテーブル)のデータを表示します。
サーバー側で全件を取得して、View側ではoptionタグにth:eachを記述して表示させます。

詳細項目の削除機能
詳細画面の削除ボタンを押すと、詳細データを削除します。
こちらも中間テーブルに対する削除処理になります。
メソッドの作り方・考え方の基本
「画面表示」用のメソッドと、「DB処理を行う」メソッドは分けて作成します。
「画面表示」用のメソッド
・GET通信
・return “”; というView表示で終わる
・画面表示するために必要な変数・パラメータを渡す
「DB処理を行う」メソッド
・POST通信
・return “redirect:/~”; といったリダイレクト処理でViewを表示するGet通信へ返す
※検索機能はGET通信でよい
具体例として、
一覧画面から新規作成画面に移動 → 新規作成画面で登録ボタンを押下 → 登録処理後、一覧画面にリダイレクト
の流れを示したのが下図です。(メソッド名は例)
この例を参考に制作を進めましょう。

ヒント、補足知識
ユニーク(重複不可)の実装例
考え方
重複データが送信された場合に、処理を実行せずにエラーとして画面に返してあげます。
考え方としては、下記のcodeカラムについてユニークとしたい場合
<新規登録>
現状テーブルに存在していなければ登録可能(code=0001で検索してデータが存在しなければOK)

<編集>
・編集時の場合、自分自身のデータは許可する必要があります。
テーブルにcode=0001のデータが存在しても、id=1で自分自身と一致するならOK

・上記のデータが存在する状態では、下記の変更はNGとなります。

実装例
簡単な実装方法としては、Controllerで実装します。
<新規登録の場合>
// 新規登録メソッド
public String entryPost(Model model, @ModelAttribute("form") @Validated EmployeeForm form, BindingResult result) {
// コードの重複チェック
Optional<Employee> employeeOpt = employeeRepository.findByCode(form.getCode());
if (employeeOpt.isPresent()) {
result.rejectValue("code", "", "このコードは登録済みのため使用できません。");
}
// エラー返却
if (result.hasErrors()) {
return entry(model, id, form);
}
//以下略
}
・上記のようにif文で重複チェック
・BindingResultのrejectValueメソッドでエラーメッセージを追加しています。
バリデーションのアノテーションがない内容でも、このように個別でバリデーションメッセージを追加することもできます。
(第2引数はエラーコードで、省略可のためから文字列を渡しています)
<編集の場合>
// 新規登録メソッド
public String editPost(Model model, @PathVariable Integer id,
@ModelAttribute("form") @Validated EmployeeForm form, BindingResult result) {
// コードの重複チェック
Optional<Employee> employeeOpt = employeeRepository.findByCode(form.getCode());
if (employeeOpt.isPresent()) {
if (employeeOpt.get().getId() != id) {
result.rejectValue("code", "", "このコードは登録済みのため使用できません。");
}
}
// エラー返却
if (result.hasErrors()) {
return entry(model, id, form);
}
//以下略
}
・自分自身のデータであるか(idが一致するか)を確認しています。
その他の実装方法(発展)
・自作アノテーションを作成
SpringBootで一意性制約のアノテーションを自作(コピペで完成) – Qiita
