Java

【Spring Boot入門】更新処理を実装する【Spring Boot ハンズオン第6回】

※アフィリエイト広告を利用しています。

エンジニア大学ではSpring Bootで簡単なWebアプリを開発する方法を発信しています。

Javaの基礎学習が終わった方へ

Spring BootでWebアプリを開発する
バリデーションチェックの実装・・・・・・前回の記事
GitHubに全コード上がっています!

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

この記事を読むことで

  • 指定したidのデータを取得する方法
  • 指定したidのデータを更新する方法

を学ぶことができます!

\\サブスク型スクールで挫折せずにエンジニアになろう//

Freeks公式サイトはこちら

まずは無料カウンセリングから

bookList.html

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

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

次のようにhref属性を指定することで、「/book-edit?id=xx」というようなリクエストを送信することができます。
このidを使って、対象のデータに対して、更新処理を行なっていきます。

<a class="btn btn-success" 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>
<link rel="stylesheet" th:href="@{/webjars/bootstrap/5.2.2/css/bootstrap.min.css}"/>
</head>
<body>
    <div th:replace="share::header"></div>
    <div class="container">
        <div class="row">
            <div th:each="book : ${bookList}" th:object="${book}" class="card col-3 me-2 mb-2" style="width: 18rem;">
                <div class="card-body">
                    <h5 class="card-title" th:text="*{title}"></h5>
                    <p class="card-text" th:text="*{price} + 円"></p>
                    <a class="btn btn-success" th:href="@{/book-edit(id=*{id})}">編集</a>
                </div>
            </div>
        </div>
        <a class="btn btn-primary mt-3" th:href="@{/book-create}">新規追加</a>
    </div>
</body>
</html>

2023/02/19にBootstrapの記事を公開しました。その影響で少し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>
<link rel="stylesheet" th:href="@{/webjars/bootstrap/5.2.2/css/bootstrap.min.css}"/>
</head>
<body>
    <div th:replace="share::header"></div>
    <div class="container">
        <h1>本の編集を行う</h1>
        <form th:action="@{/book-edit}" th:object="${editBookForm}" method="POST">
            <input type="hidden" th:field="*{id}" th:value="*{id}" />
            <div class="mb-3">
                <p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-danger">Title Error</p>
                <label for="bookTitle" class="form-label">タイトル</label>
                <input id="bookTitle" class="form-control" type="text" th:field="*{title}">
            </div>
            <div class="mb-3">
                <p th:if="${#fields.hasErrors('price')}" th:errors="*{price}" class="text-danger">Price Error</p>
                <label for="bookPrice" class="form-label">値段</label>
                <input id="bookPrice" class="form-control" type="number" th:field="*{price}">
            </div>
            <input type="submit" class="btn btn-primary" value="更新">
        </form>
        <a th:href="@{/book-list}" class="btn btn-secondary">一覧に戻る</a>
    </div>
</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」にアクセスすると一覧画面が表示され、編集ボタンが表示されています。

編集ボタンが表示される

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

編集画面に遷移

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

バリデーションチェックも有効

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

今回の記事はここまでです。次はいよいよ最後、削除機能を実装します。

次の記事はこちら

挫折せずにプログラミングを学ぶためには?

僕はプログラミングで挫折した経験があります。

エラーの連続やエラーが解消しても思った通りに動かないといったことが原因で、プログラミングが嫌いでした。

当時はパソコンの基礎すら分からず、Googleでの検索力もありませんでした。

「プログラミングって全然意味わからないし、全然楽しくない」そう思っていました。

そんな僕でも今はエンジニアとして働けています。

エンジニアとなった今、初心者の方は周りの人に聞ける環境というのがとても大切だと感じています。

周りに聞ける人がいない時は、学習環境を手に入れるためにお金を払うというのも一つの方法です。

それができるのが、プログラミングスクールのFreeksです。

Freeksは月額10,780円で現役エンジニアに質問する環境を手に入れることができるプログラミングスクールです。

多くのプログラミングスクールが数十万円払って通うところを月額10,780円から通うことができるのはコスパが良いです。

しかもサブスク制で、自分のペースで学ぶことができ嫌になったらすぐにやめることができます。

Freeksでは無料カウンセリングを行なっています。

「周りに誰も聞ける人がいなくて、エラーが解決できない」「プログラミング全然楽しくない」という方は、無料カウンセリングを受けてみて下さい。

\\質問できる環境を手に入れて効率よく学ぼう//

Freeks公式サイトはこちら

まずは無料カウンセリングから

【関連記事】Freeks評判、口コミ

-Java
-, ,