Spring bootで簡単なWebアプリを作ってみた

## 前提
私個人の手順書を兼ねてメモをします。

## 作るもの
夫婦間で共有するTodoリストアプリです。
MVPで作っていくので、どんどん機能改善していきたいと思っています。


## 使用する技術
* Docker
* Spring Boot
* MySQL(Ver8.0)


DBアクセスにはJPA,viewはThymeleafを使用。

## ディレクトリ構成
[このサイト※1](https://blog.mmmcorp.co.jp/blog/2019/02/22/java11_springboot_docker/)wo
を参考にしました。
案件によってディレクトリ構成が異なるので、いつも迷ってしまう。
Controller, Service, Repository の

```
root/webapp/src/main
└── java/com/example/todo
│    ├── DemoApplication.java
│    ├── domain
│    │   └── Task.java
│    ├── controller
│    │   └── TaskController.java
│    ├── service
│    │   └── TaskService.java
│    └── repository
│        └── TaskRepository.java
└── resources
     ├── application.yml
     ├── static
     └── templates
         └── index.html
```


## MySQLをDockerで使うための準備
MySQLは、Docker 公式のイメージを用います。バージョンは8.0。
Flywayを使わなくても初期化できるみたいなので、Flywayの使用は一旦やめます。

```
root
├── webappc
├── build.gradle
├── log
│   └── mysql
│       └── mysqld.log
├── docker
│   └── mysql
│       ├── Dockerfile
│       ├── conf.d
│       │   └── my.cnf
│       └── initdb.d
│           ├── R__insert_tasks_table.sql
│           └── V20220627_1__create_all_table.sql
├── docker-compose.yml

```


MySQLの文字コードの設定
```my.conf
[mysqld]
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4
```

```V20220627_1__create_all_table.sql
CREATE TABLE IF NOT EXISTS tasks (
    id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    description VARCHAR(255) NOT NULL,
    created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

```


```R__insert_tasks_table.sql
INSERT INTO tasks(id, description) VALUES (1, 'これはサンプルタスクです。') as EXPR
    ON DUPLICATE KEY UPDATE id = EXPR.id;
```

```docker-compose.yml
version: "3.6"
services:
  db:
    container_name: mysql-db # コンテナ名
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root # rootユーザのパスワードを指定
      MYSQL_USER: user #　ここで指定したユーザが自動生成される
      MYSQL_PASSWORD: user # MYSQL_USERのパスワード
      MYSQL_DATABASE: todo_app # ここで指定した名前でDBが自動生成される
      TZ: "Asia/Tokyo" # TimeZoneの指定
    command: --default-authentication-plugin=mysql_native_password # mysql_native_password を使用したネイティブ認証。これを指定しないとエラーになる。
    ports:
      - 3306:3306
    volumes:
      - ./docker/mysql/conf.d:/etc/mysql/conf.d # my.confのマッピング
      - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d DB初期化処理のスクリプト配置場所
      - ./docker/storage:/var/lib/mysql # データ保存場所のマッピング
      - ./log/mysql:/var/log/mysql # ログ保存場所のマッピング 
  app:

```

## 苦労した点
* MySQLのコンテナ起動時の初期化スクリプトが起動しなかった。
-> `docker-compose.yml`に定義するvolumesの定義を変更したら動作するようになった。

```:変更前
services:
  db:
    volumes:
      - ./docker/storage:/var/lib/mysql # データ保存場所のマッピング
```

```:変更後
services:
  db:
    volumes:
      - mysql_db:/var/lib/mysql # データ保存場所のマッピング

volumes:
  mysql_db:
    driver: local
```


## 将来的に追加したい機能

- [ ]  Andoroidアプリ化して指紋認証ログイン機能
- [ ]  Todo削除機能
- [ ]  Public Cloudにデプロイ(DBはAzure Cosmos DBのFree Tierを使用したい)
- [ ]  FlywayでDBテーブルのバージョン管理
- [ ]  Gitでバージョン管理
- [ ]  Public Cloudにコンテナをデプロイ。
- [ ]  Unit Testコードの充実
- [ ]  設計書の作成（クラス図、ER図、シーケンス図、画面遷移図など）
- [ ]  taskテーブルにcreated,updatedを追加する
- [ ]  Todo追加機能

## 参考にしたサイト

* ※1 [Java11+Spring Boot+Dockerで作るWebアプリケーション](https://blog.mmmcorp.co.jp/blog/2019/02/22/java11_springboot_docker/)
* [完全コンテナベースのローカル開発環境を構築する（Docker+Spring Boot+MySQL+Flyway+Spock）](https://qiita.com/chiggg/items/4976615fe98d5a437011#docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E8%A8%AD%E5%AE%9A)
* [Docker(Compose)を使ったローカル開発用MySQLの準備](https://qiita.com/taqm/items/8b6b896ec4a9a0b84886)