MyBatisお試し #4 データ削除

## Prev

https://qiita.com/yamashun38/items/0d8991711435d15c423b#prev

## 概要
- 業務でMyBatisを使用することがあったので理解度向上のために自宅でも色々触ってみる
- 下記のような操作が可能なアプリを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/d25c23c7-7d5d-0f52-ecf4-e9dcde43b561.png)

## ソースコード

https://github.com/yamashun38/MyBatis

## ユーザ削除
- 指定したIDに対応するユーザ情報を削除できるよう実装
- [ユーザ検索](https://qiita.com/yamashun38/items/7731d5ca3da41250fc31)と同様、指定したIDに対応するユーザが存在しない場合はエラー画面を表示

### UserMapper.xml

```xml:UserMapper.xml
    <!-- 指定されたIDのユーザを削除 -->
    <delete id="delete" parameterType="int">
        DELETE FROM
            users
        WHERE
            id = #{id}
    </delete>
```

- 指定したIDに対応するユーザのデータを削除
- 引数としてIDが渡される

### UserMapper.java

```java:UserMapper.java
    /**
     * データを削除
     */
    int delete(int id) throws UserNotFoundException;
```

- IDを引数として受け取りSQL文を実行する
- ユーザが存在しない場合は`UserNotFoundException`を投げる

### UserLogic.java

```java:UserLogic.java
    /**
     * deleteメソッドを呼び出し
     * データを削除
     */
    public void deleteUser(UserDto userDto) throws UserNotFoundException {

        findUser(userDto);
        userMapper.delete(userDto.getId());
    }
```

- 最初に`findUser`メソッドを呼び出すことにより指定したIDのユーザが存在するかどうかのチェックを実施
- ユーザが存在しない場合はエラーを投げる
- 存在する場合はdeleteメソッドを呼び出しユーザ情報の削除を実施

### MybatisController.java

```java:MybatisController.java
    /**
     * ユーザ削除画面表示
     */
    @GetMapping("/userDelete")
    public String delete() {

        return "delete/userDelete";
    }

    /**
     * ユーザ削除完了画面表示
     */
    @GetMapping("/deleteComplete")
    public String delete(@RequestParam("id") int id, Model model) {

        try {
            userDto.setId(id);
            userLogic.deleteUser(userDto);
        } catch (UserNotFoundException e) {
            model.addAttribute("errorMessage", e.getMessage());
            return "delete/deleteComplete";
        }
        model.addAttribute("deleteMessage", "削除が完了しました。");
        return "delete/deleteComplete";
    }
```

- [localhost:8080/userDelete](localhost:8080/userDelete)にアクセスすることで、削除したいユーザのIDを入力する画面へ遷移
- 削除ボタンを押下すると入力したIDがGETメソッドによって[localhost:8080/deleteComplete](localhost:8080/deleteComplete)に渡される
- ユーザが存在する場合はdeleteUserメソッドにより削除を実行し、`deleteMessage`をビューへ返す
- ユーザが存在しない場合はエラーメッセージをビューへ返す

### userDelete.html
- 削除するユーザのID入力画面

```html:userDelete.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>ユーザ削除</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container mt-3">
        <h1>ユーザ削除</h1>
        <form th:action="@{/deleteComplete}" method="get">
            <div class="mb-3">
                <label for="userId" class="form-label">ユーザID</label>
                <input type="number" class="form-control" id="userId" name="id" required>
            </div>
            <button type="submit" class="btn btn-primary">削除</button>
        </form>

        <a th:href="@{/main}" class="btn btn-secondary mt-3">メイン画面へ戻る</a>
    </div>
</body>

</html>
```

- `th:action`によって削除ボタンを押下した際の遷移先を指定
- `method`によってメソッドを指定
- 今回は削除ボタンを押下するとGETメソッドにによってフォームに入力したIDを[localhost:8080/deleteComplete](localhost:8080/deleteComplete)へ渡すよう実装

### deleteComplete.html
- 削除完了画面

```html:deleteComplete.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>ユーザ一覧</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container mt-3">
        <h1>削除結果</h1>
        <!-- 指定したIDのユーザが存在しない場合 -->
        <div th:if="${errorMessage}">
            <p th:text="${errorMessage}">指定したユーザは存在しません。</p>
        </div>
        <!-- 指定したIDのユーザが存在する場合 -->
        <div th:if="${deleteMessage}">
            <p th:text="${deleteMessage}">削除が完了しました。</p>
        </div>

        <a th:href="@{/allUsers}" class="btn btn-secondary mt-3">ユーザ一覧へ</a>
        <a th:href="@{/main}" class="btn btn-secondary mt-3">メイン画面へ戻る</a>
    </div>
</body>

</html>
```

- ユーザ検索の際と同様、`th:if`によりエラーメッセージが渡された場合と削除完了メッセージが渡された場合の条件分岐を実施

### ユーザ削除
#### ユーザが存在する場合
- IDが`1`のユーザを削除してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/ef40dce4-bed4-221c-ab6b-99107f30998c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/a0694e9b-6525-52db-ce40-fc5ad144e589.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/643ca5b2-e8b1-31db-b5ae-bbdf4654b030.png)

#### ユーザが存在しない場合
- IDが`5`のユーザ(存在しない)を削除しようとする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/ef67edc6-a0ec-9866-0de6-a68d07a92152.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757184/d7248a3b-ac07-e9b3-a7c7-6a983f30fcb7.png)

## Next

https://qiita.com/yamashun38/items/bc423e38cde3dc841684