【頑張れば5分で作れる】Spring Boot + MyBatisで超簡単なCRUD処理のREST APIを作る【VSCode】

CRUD処理のあるSpring Bootアプリを急いで作ったらどれくらい早くできるのか挑戦したところ...
**5分で作ることができました！**

<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/OYX8kljQklo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

今回はこちらの動画の解説記事になります。
CRUD(Create/Read/Update/Delete)処理をREST APIで実装していきます。

# 開発環境

- Windows 10
- Visual Studio Code
    - (↓主な拡張機能)
    - Extension Pack for Java
    - Lombok Annotations Support for VS Code
    - Spring Boot Extension Pack
- Postman
- Java 11
- Maven
- MySQL 8.0

# データベースとテーブルの作成

MySQLで事前にデータベースとテーブルを作成しておきます。

今回は以下のようなテーブルを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/3bf020ab-a65e-63a5-d241-0ecbfccfb1dd.png)

```sql
CREATE TABLE users(
	id INT AUTO_INCREMENT PRIMARY KEY,
	name VARCHAR(100)
);
```


# Spring Bootプロジェクトの作成

`Ctrl + Shift + P`[^1]でコマンドパレットを開き、`Spring Initializr: Create a Maven project...`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/619203ce-9696-fb34-19c0-0a33457ec530.png)


バージョン選択などの質問がいくつか出てきますが、最後の依存関係以外はデフォルトで問題ないので、Enterキーを6回押します。

最後の質問である`Spring Initializr: Choose dependencies`では、以下の4つの依存関係を追加します。

- Spring Web
- MySQL Driver
- MyBatis Framework
- Lombok

依存関係を追加し終わったら、`Selected 4 dependencies`にカーソルが合った状態でEnterを押すと、プロジェクトのひな型がダウンロードされます。

次に、ダウンロードされたSpring Bootプロジェクトを開いてコードを書いていきます。

# application.properties

`Ctrl + P`でファイルを名前で検索できるので、`app`と入力して先頭に出てきたapplication.propertiesを開いて編集します。

```properties:application.properties
spring.datasource.url=jdbc:mysql://<ホスト名>:<ポート>/<データベース名>
spring.datasource.username=<ユーザー名>
spring.datasource.password=<パスワード>
```

(今回の動画の場合)

```properties:application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=root
```

# User.java

DemoApplication.javaと同じディレクトリに、User.javaを作成します。これはモデル、エンティティ、またはDTOと言われるものです。

```java:User.java
package com.example.demo;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {

    private int id;
    private String name;
}
```

# UserMapper.java

先程と同じディレクトリに、UserMapper.javaを作成します。クラスではなくインターフェースなので注意です。また、今回の環境ではSQL部分の入力チェックや補完が効かないのでミスしやすいです。

```java:UserMapper.java
package com.example.demo;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

@Mapper
public interface UserMapper {

    @Insert("insert into users (name) values (#{name})")
    public boolean create(String name);

    @Select("select * from users")
    public List<User> read();

    @Update("update users set name = #{name} where id = #{id}")
    public boolean update(int id, String name);

    @Delete("delete from users where id = #{id}")
    public boolean delete(int id);

}
```

# UserController

先程と同じディレクトリに、UserController.javaを作成します。

```java:UserController.java
package com.example.demo;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @Autowired
    UserMapper userMapper;

    @PostMapping("")
    public boolean create(@RequestBody String name) {
        return userMapper.create(name);
    }

    @GetMapping("")
    public List<User> read() {
        return userMapper.read();
    }

    @PatchMapping("/{id}")
    public boolean update(@PathVariable int id, @RequestBody String name) {
        return userMapper.update(id, name);
    }

    @DeleteMapping("/{id}")
    public boolean delete(@PathVariable int id) {
        return userMapper.delete(id);
    }

}
```

# アプリの起動

サイドバーのエクスプローラーのSPRING BOOT DASHBOARDから、アプリを起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/80d95992-18a7-00fc-5f0f-c0f1875d17f7.png)

# 動作確認

APIの動作確認には、Postmanというソフトを使用します。

Read処理として、usersテーブルのデータをGETリクエストで取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/e47e4387-077b-0d86-a54a-9ac8d6cc79de.png)

まずはこちらのGETリクエストを送ってみると、データがまだ無いため空のオブジェクト`[]`が返ってきました。

次に、Create処理として、POSTリクエストを送ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/b30034b9-1312-8d53-9288-959bdb5d0f0a.png)

リクエストボディで渡した名前のユーザーを作成するAPIになっています。今回はリクエストボディに`太郎`という文字列を含めています。

POSTリクエストには`true`が返ってきました。

ここでもう一度GETリクエストでusersテーブルの中身を確認してみると、idが`1`、nameが`太郎`のレコードが作成されていることが分かります。

次に、Update処理として、PATCHリクエストを送ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/8e8cc02d-de0a-b902-953f-c496891ea91a.png)

パスパラメータでid、リクエストボディで名前を渡して、指定したidのユーザーの名前を更新するAPIになっています。

PATCHリクエストには`true`が返ってきました。

もう一度GETリクエストでusersテーブルの中身を確認してみると、idが`1`のユーザーのnameが`太郎`から`たろう`に更新されていることが分かります。

最後に、Delete処理として、DELETEリクエストを送ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1183281/20232638-7344-5294-ac83-d81e223d23c9.png)

パスパラメータで渡したidのユーザーを削除するAPIになっています。

DELETEリクエストには`true`が返ってきました。

もう一度GETリクエストでusersテーブルの中身を確認してみると、空のオブジェクト`[]`が返ってきました。

以上です。

# 最後に

EclipseやIntellij IDEAではどれだけ早く作れるのか気になるので、挑戦をお待ちしています！！

[^1]: ※キーボードショートカットは初期設定のものを紹介しています。