スポンサーリンク

Webアプリケーション開発

SpringBootで削除画面を作成する

投稿日:

削除画面のサンプル

画面デモ

このサンプルコードで、次のような画面を作成します。
削除するだけの簡易な画面になります。

ディレクトリ構成

project-root/src
 ├── main
 │   ├── java
 │   │   └── com
 │   │       └── springhack
 │   │           └── okozukaisystem
 │   │               ├── OkozukaiSystemApplication.java
 │   │               ├── business
 │   │               │   └── ChildrenService.java
 │   │               ├── domain
 │   │               │   └── Child.java
 │   │               ├── integration
 │   │               │   ├── entity
 │   │               │   │   └── ChildrenEntity.java
 │   │               │   └── mapper
 │   │               │       └── ChildrenMapper.java
 │   │               └── presentation
 │   │                   ├── children
 │   │                   │   ├── ChildrenController.java
 │   │                   │   └── ChildrenControllerHelper.java
 │   └── resources
 │       ├── com
 │       │   └── springhack
 │       │       └── okozukaisystem
 │       │           └── integration
 │       │               └── mapper
 │       │                   └── ChildrenMapper.xml
 │       └── templates
 │           ├── children
 │           │   ├── index.html
 │           │   └── remove.html

テーブル構造

このサンプルでは下記のテーブルを使用します。

child_idBIGINT
nameVARCHAR(50)
birthdayDATE
children

削除のコントローラー層

@Controller
public class ChildrenController {

    private final ChildrenService childrenService;

    public ChildrenController(ChildrenService childrenService) {
        this.childrenService = childrenService;
    }

    @RequestMapping("/children")
    public String index(Model model) {

        // 子どもリストを取得
        List<Child> children = childrenService.getAll();

        // 画面表示
        model.addAttribute("children", children);
        return "children/index";
    }


    @GetMapping("/children/remove")
    public String remove(Long id, Model model) {

        // 削除チェック
        Child child = childrenService.get(id);
        if (Objects.isNull(child)) {
            model.addAttribute("message", "選択した子どもが存在しません。");
            return "children/index";
        }

        // 画面遷移
        model.addAttribute("child", child);
        return "children/remove";
    }

    @PostMapping("/children/removeFinish")
    public String removeFinish(Long childId, Model model, RedirectAttributes redirectAttributes) {

        // 削除チェック
        Child child = childrenService.get(childId);
        if (Objects.isNull(child)) {
            model.addAttribute("message", "選択した子どもが存在しません。");
            return "children/index";
        }

        // 削除実行
        childrenService.remove(childId);

        // 画面遷移
        redirectAttributes.addFlashAttribute("message", "子ども削除しました。");
        return "redirect:/children";
    }
}

削除のサービス層

@Service
public class ChildrenService {

    private final ChildrenMapper childrenMapper;

    public ChildrenService(ChildrenMapper childrenMapper) {
        this.childrenMapper = childrenMapper;
    }

    /**
     * 全件取得する
     */
    public List<Child> getAll() {
        // DBから取得
        List<ChildrenEntity> allChildren = childrenMapper.selectAll();
        var children = allChildren
                .stream()
                .map(child -> new Child(child.getChildId(), child.getName(), child.getBirthday()))
                .collect(Collectors.toList());
        return children;
    }

    /**
     * 1件取得する
     */
    public Child get(Long childId) {
        ChildrenEntity childrenEntity = childrenMapper.findById(childId);
        if (Objects.isNull(childrenEntity)) {
            return null;
        }
        return new Child(
                childrenEntity.getChildId(),
                childrenEntity.getName(),
                childrenEntity.getBirthday());
    }

    /**
     * 削除する
     */
    public void remove(Long childId) {
        childrenMapper.delete(childId);
    }
}

削除のインテグレーション層

@Mapper
public interface ChildrenMapper {
    List<ChildrenEntity> selectAll();
    ChildrenEntity findById(Long childId);
    void delete(Long childId);
}

DB接続にはMybatisを使用しました。
そのため、@Repositoryではなく@Mapperを付与したインターフェースを作成し、命名は「テーブル名+Mapper」とします。


<mapper namespace="com.springhack.okozukaisystem.integration.mapper.ChildrenMapper">
    <select id="selectAll" resultType="com.springhack.okozukaisystem.integration.entity.ChildrenEntity">
        SELECT c.child_id, c.name, c.birthday FROM children c
    </select>

    <select id="findById" resultType="com.springhack.okozukaisystem.integration.entity.ChildrenEntity">
        SELECT c.child_id, c.name, c.birthday FROM children c WHERE c.child_id = #{childId}
    </select>

    <delete id="delete">
        DELETE FROM children WHERE child_id = #{childId}
    </delete>
</mapper>

Mybatisの場合は、ネイティブSQLを使用しますので、
MapperのselectAllとinsertに対するSQLを定義しておきます。


@AllArgsConstructor
@Data
public class ChildrenEntity {
    private Long childId;
    private String name;
    private LocalDate birthday;
}

Childrenテーブルに対するエンティティを作成します。
MybatisでSELECT結果を自動で格納させるために、@AllArgsConstructorを付与します。

削除で使用するモデル

@AllArgsConstructor
@Getter
public class Child {

    /** ID */
    private Long childId;

    /** 名前 */
    private String name;

    /** 誕生日 */
    private LocalDate birthday;
}

削除画面のビュー

一覧表示画面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>子どもマスタ|子どものお小遣い帳アプリ</title>
</head>
<body>
    <header></header>
    <main>
        <h1>子どもマスタ</h1>
        <div th:text="${message}"></div>
        <table border="1">
            <tr>
                <th>名前</th>
                <th>生年月日</th>
                <th>年齢</th>
                <th>操作</th>
            </tr>
            <tr th:each="child: ${children}">
                <td th:text="${child.name}"></td>
                <td th:text="${child.birthday}"></td>
                <td>TODO</td>
                <th>
                    <button th:attr="onclick='location.href=\'/children/edit?id=' + ${child.childId} + '\''">編集</button>
                    <button th:attr="onclick='location.href=\'/children/remove?id=' + ${child.childId} + '\''">削除</button>
                </th>
            </tr>
        </table>
        <a href="/children/register">子どもを登録</a>
    </main>
    <footer>
        <a href="/">トップページ</a>
    </footer>
</body>
</html>

削除確認画面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>子どもマスタ|子どものお小遣い帳アプリ</title>
</head>
<body>
    <header></header>
    <main>
        <h1>子どもを削除</h1>
        <div>この子どもを削除します。よろしいですか?</div>
        <form method="POST" action="/children/removeFinish" th:object="${child}">
            <table border="1">
                <tr>
                    <th>名前</th>
                    <td th:text="*{name}"></td>
                </tr>
                <tr>
                    <th>生年月日</th>
                    <td th:text="*{birthday}"></td>
                </tr>
            </table>
            <input type="hidden" th:field="*{childId}">
            <button onclick="location.href='/children';return false;">キャンセル</button>
            <input type="submit" value="削除を確定する" />
        </form>
    </main>
    <footer>
        <a href="/">トップページ</a>
    </footer>
</body>
</html>

Udemyのハンズオン動画講座でSpringBootのスキルを磨く!

スポンサーリンク

-Webアプリケーション開発

Copyright© 【Spring Hack】 , 2022 All Rights Reserved Powered by AFFINGER5.