【Spring Boot入門】更新処理を実装する

Java

今回の記事ではSpring Bootで既にデータベースに存在しているデータの更新処理を実装します。

今回作成する更新機能の処理の流れを図にすると次のようになります。
記事を進めながら、参考にしてみてください。

list.html

まずは一覧画面の編集を行います。

一覧表示はこちらの記事を参考にしてみてください。
【Spring Boot】PostgreSQLに接続してデータを取得する

一覧画面では本のデータに加えて、「編集」リンクを新しく追加します。

次のように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タグを使って、画面で保持し、「更新」ボタンが押されたときにサーバーに送ります。

送られてきたサーバーを元に、データベースの更新処理を行います。

<input type="hidden" th:field="*{id}" th:value="*{id}">

そのほかのフォームなどのやり取りに関してはこちらの記事も参考にしてみてください。
【Spring Boot入門】フォームから値を取得してデータベースに登録する

<!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を保持するようにし、各フィールド毎にバリデーションの設定もしました。

バリデーションについてはこちらの記事も参考にしてみてください。
Spring Bootでバリデーションチェックを実装する

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」メソッドではリクエストデータから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";
}

「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の全体はおおむね次のようになります。

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」メソッドでは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;
}

「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);
}

こちらも途中で省略していますが、全体像としては次のようになります。

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);
	}
}

今回はSpring Bootで更新処理を実装する方法について解説しました。

このようにこのサイトではプログラミング初心者や未経験の学生や社会人の方に向けて、JavaでWebアプリを開発する方法を発信しています。

プログラミングを勉強して、エンジニアになりたい!」という方はぜひこのサイトを参考に、エンジニアを目指してください!
プログラミング未経験からエンジニアになるまでのロードマップ

タイトルとURLをコピーしました