
uhablogではSpring Bootで簡単なWebアプリを開発する方法を発信しています。
Javaの基礎学習が終わった方へ
今回の記事ではSpring Bootで既にデータベースに存在しているデータの更新処理を実装します。
この記事を読むことで
- 指定したidのデータを取得する方法
- 指定したidのデータを更新する方法
を学ぶことができます!
今回作成する更新機能の処理の流れを図にすると次のようになります。
記事を進めながら、参考にしてみてください。

list.html
まずは一覧画面の編集を行います。
一覧画面の記事はこちら
一覧画面では本のデータに加えて、「編集」リンクを新しく追加します。
次のようにhref属性を指定することで、「/book-edit?id=xx」というようなリクエストを送信することができます。
このidを使って、対象のデータに対して、更新処理を行なっていきます。
<a th:href="@{/book-edit(id=*{id})}">編集</a>
「bookList.html」全体は次のようになります。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本の一覧表示</title>
</head>
<body>
<table>
<tr th:each="book : ${bookList}" th:object="${book}">
<td th:text="*{id}"></td>
<td th:text="*{title}"></td>
<td th:text="*{price}"></td>
<!-- ここを追加 -->
<td><a th:href="@{/book-edit(id=*{id})}">編集</a></td>
</tr>
</table>
<a th:href="@{/book-create}">新規登録</a>
</body>
</html>
edit.html
次に本の編集を行う画面である「edit.html」を作成します。
ポイントはhiddenタグでidを保有していることです。
idはデータベースから取得したものをhiddenタグを使って、画面で保持し、「更新」ボタンが押されたときにサーバーに送ります。
送られてきたidを元に、データベースの更新処理を行います。
<input type="hidden" th:field="*{id}" th:value="*{id}">
edit.htmlは次のようになります。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>本の情報の編集を行います</title>
</head>
<body>
<h1>本の編集を行う</h1>
<form th:action="@{/book-edit}" th:object="${editBookForm}" method="POST">
<input type="hidden" th:field="*{id}" th:value="*{id}">
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}">Title Error</p>
タイトル:<input type="text" th:field="*{title}" th:value="*{title}"><br>
<p th:if="${#fields.hasErrors('price')}" th:errors="*{price}">Price Error</p>
値段 :<input type="number" th:field="*{price}" th:value="*{price}"><br>
<input type="submit" value="更新">
</form>
<a th:href="@{/book-list}">一覧に戻る</a>
</body>
</html>
フォームの入力値を受け取る方法やバリデーションチェックを行う方法は次の記事も参考にしてみてください。
データ登録やバリデーションはこちら
EditBookForm.java
新規で編集機能ようのFormクラスを作成します。
こちらは、id, title, priceを保持するようにし、各フィールド毎にバリデーションの設定もしました。
package com.uhablog.form;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
import lombok.Data;
@Data
public class EditBookForm {
/**
* 本のIDを保持する
* チェック内容:Nullでないこと
*/
@NotNull(message="IDがNullになっています")
private Integer id;
/**
* 本のタイトルを保持する
* チェック内容:未入力でないこと
*/
@NotBlank(message="タイトルを入力してください")
private String title;
/**
* 本の値段を保持する
* チェック内容:Nullでないこと、プラスであること
*/
@NotNull(message="値段を入力してください")
@Positive(message="値段はプラスの値を入力してください")
private Integer price;
}
BookController.java
次に「BookController.java」の編集を行います。
一覧画面でリンクが押されたときに編集画面を表示する「editBook」メソッドと、編集画面で入力された値で更新処理を実行する「update」メソッドを作成しました。
editBookメソッド
「editBook」メソッドではリクエストデータからidを取得して、serviceクラスのgetOneBookメソッドを呼び出して、編集対象のデータを取得しています。
取得したデータをmodelに設定して、編集画面を表示しています。
serviceクラスの処理については後ほど解説します。
// 編集画面を表示する
@GetMapping("/book-edit")
public String editBook(Model model, EditBookForm editBook) {
editBook = service.getOneBook(editBook.getId());
model.addAttribute(editBook);
return "edit";
}
・データベースからidを指定してデータを取得
・編集画面を表示
updateメソッド
「update」メソッドでは編集画面で編集された値を受け取って、更新処理を行います。
入力された値のバリデーションチェックを行い、エラーがあった場合は、編集画面をもう一度表示します。
入力値が正常だった場合は、serviceクラスのupdateメソッドを実行して、データの更新を行います。
その後、リダイレクトを使って、一覧画面を表示します。
// 本の情報を更新する
@PostMapping("/book-edit")
public String update(@ModelAttribute @Validated EditBookForm editBook, BindingResult result, Model model) {
// バリデーションエラーの場合
if (result.hasErrors()) {
// 編集画面に遷移
return "edit";
}
// 本を更新する
service.update(editBook);
// 本の一覧画面にリダイレクト
return "redirect:/book-list";
}
・バリデーションでエラーがあれば編集画面を再表示
・エラーがなければデータを更新して一覧画面を表示
Controller全体
コードが長いので、途中で省略していますが、Controllerの全体はおおむね次のようになります。
package com.uhablog.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.uhablog.form.BookForm;
import com.uhablog.form.EditBookForm;
import com.uhablog.model.Book;
import com.uhablog.service.BookService;
@Controller
public class BookController {
@Autowired
BookService service;
// 本の一覧画面を表示する
@GetMapping("/book-list")
public String bookList(Model model) {
// serviceを使って、本の一覧をDBから取得する
List<Book> bookList = service.findAll();
// modelに本の一覧を設定して、画面に渡す
model.addAttribute("bookList", bookList);
// bookList.htmlの表示
return "bookList";
}
・
・
・
// 編集画面を表示する
@GetMapping("/book-edit")
public String editBook(Model model, EditBookForm editBook) {
editBook = service.getOneBook(editBook.getId());
model.addAttribute(editBook);
return "edit";
}
// 本の情報を更新する
@PostMapping("/book-edit")
public String update(@ModelAttribute @Validated EditBookForm editBook, BindingResult result,Model model) {
// バリデーションエラーの場合
if (result.hasErrors()) {
// 編集画面に遷移
return "edit";
}
// 本を更新する
service.update(editBook);
// 本の一覧画面にリダイレクト
return "redirect:/book-list";
}
}
BookService.java
最後にServiceクラスを編集します。
Serviceクラスではidを受け取って、データを取得する「getOneBook」メソッドとデータの更新処理を行う「update」メソッドを実装します。
getOneBookメソッド
「getOneBook」メソッドではrepositoryのfindByIdメソッドを使って、データを取得します。
取得したデータを画面に表示するEditBookFormの形に整形して、返却します。
// 受け取ったidからデータを取得して、Formを返却する
public EditBookForm getOneBook(Integer id) {
// idを指定して本の情報を取得する
Book book = repository.findById(id).orElseThrow();
// 画面返却用のFormに値を設定する
EditBookForm editBook = new EditBookForm();
editBook.setId(book.getId());
editBook.setTitle(book.getTitle());
editBook.setPrice(book.getPrice());
return editBook;
}
・idを指定してデータを取得
・EditBookFormに変換して、データを返却
updateメソッド
「update」メソッドでは画面で入力された値を保持するEditBookFormを更新用にBookに変換して、repositoryのsaveメソッドを使って、更新処理を行います。
// 本を更新する
public void update(EditBookForm editBook) {
// データベースに登録する値を保持するインスタンスの作成
Book book = new Book();
// 画面から受け取った値を設定する
book.setId(editBook.getId());
book.setTitle(editBook.getTitle());
book.setPrice(editBook.getPrice());
// データベースを更新する
repository.save(book);
}
・入力られたデータBookに詰める
・データを更新する
Serviceの全体像
こちらも途中で省略していますが、全体像としては次のようになります。
package com.uhablog.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.uhablog.form.BookForm;
import com.uhablog.form.EditBookForm;
import com.uhablog.model.Book;
import com.uhablog.repository.BookRepository;
@Service
@Transactional
public class BookService {
@Autowired
BookRepository repository;
// データベースから本の一覧を取得する
public List<Book> findAll() {
return repository.findAll();
}
・
・
・
// 受け取ったidからデータを取得して、Formを返却する
public EditBookForm getOneBook(Integer id) {
// idを指定して本の情報を取得する
Book book = repository.findById(id).orElseThrow();
// 画面返却用のFormに値を設定する
EditBookForm editBook = new EditBookForm();
editBook.setId(book.getId());
editBook.setTitle(book.getTitle());
editBook.setPrice(book.getPrice());
return editBook;
}
// 本を更新する
public void update(EditBookForm editBook) {
// データベースに登録する値を保持するインスタンスの作成
Book book = new Book();
// 画面から受け取った値を設定する
book.setId(editBook.getId());
book.setTitle(editBook.getTitle());
book.setPrice(editBook.getPrice());
// データベースを更新する
repository.save(book);
}
}
動作確認
実際にサーバーを起動して動作確認をしてみましょう。
サーバーを起動して「http://localhost:8080/book-list」にアクセスすると一覧画面が表示され、編集リンクが表示されています。

「編集」リンクを押すと本の情報が表示された編集画面に遷移します。

タイトルを未入力、値段をマイナスの値にして「更新」ボタンを押すとエラ〜メッセージが表示されます。

正しい値を入力して、更新ボタンを押すと一覧画面が表示され、データが変わっていることがわかります。

プログラミング学習はUdemyがおすすめ
私はプログラミングの学習はUdemyで行うのが一番おすすめです。
Udemyでは動画講座でプログラミングなどのスキルを身につけることができます。
現役エンジニアがUdemyをオススメする理由は
・動画で好きなときに学べる
・一流の講師に学ぶことができる
・講師の方に質問ができる
・返金保証もある
・セールを頻繁に開催している
といったたくさんの理由があります。
現在Udemyではセールを開催しています!
通常時1万円から2万円前後の価格で講座が販売されていますが、セール時には1500円前後(ランチ代くらい)で一つの講座を購入することができます。
UdemyにはSpring BootでWebアプリの開発を学べる講座もあるので、Javaの基礎を動画で学んでみたい!という方はチェックしてみてください。
独学が不安な人へ
独学で学んでいく意志がある方にはUdemyなどで学習するのがおすすめですが、プログラミングを独学するにはそれなりにハードルがあります。
- プログラミングで一度挫折した経験がある
- 一人で学習する自信がないので、サポートが欲しい
という方にはプログラミングスクールを検討してみるのがおすすめです。