Springで作るWebアプリ作成の流れ（２）バックエンドの概要

## はじめに
　この記事ではWebアプリでのバックエンドはどのような流れで動くのかについて書いていきます。

## MVCモデル
　<a href="https://qiita.com/Mizut452/items/6641c52893d769c39a67">(０)の前提知識</a>でもお話しましたが、Webアプリのテンプレート、デザインパターンとしてMVCモデルが存在します。MVCモデルとはユーザからのリクエストをModel, View, Controllerの３つの処理層に分けて処理していくというデザインパターンです。
　Web開発においてはこのMVCモデルを基礎にして作成されます。

## 今回の概要
　今回作るアプリは簡単なTODOアプリで登録したTODOがページに反映されることを目標に作成していきます。今回のアプリの流れをMVCモデルに合わせて具体的に示すと、ユーザがTODOの作成をリクエストとして送り、そのリクエストをコントローラーが受け取り、モデルが処理をして、ビューを返し、ユーザに返すという流れで行います。

　![無題のプレゼンテーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/9f40a0fe-68c2-9f5f-2ecb-321ca8f7759f.png)

## JDBCTemplateとは
　今回はDB接続などの設定を簡単にできるJDBCTemplateを使用します。
　JDBCTemplateは接続に関する`application.properties`の設定、入れるテーブル、データの設定の`data.sql`、`schema.sql`、そして接続までの設定の`DAOファイル`と`Serviceクラス`の作成で使用することができます。

　JDBCTemplate（他のライブラリを使用しても同じ？）では、MVCモデルをさらに詳細化して使用します。

![無題のプレゼンテーション (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850098/490b8249-84ec-2058-6abc-c8588089562d.png)

　上の図のようにModelの部分がServiceクラスとDAOクラスの２つに分かれ、DAOクラスではDBなどに接続しデータの更新の記述を書き、そのクラスを実装し、実行するServiceクラスに分けます。

## 各ファイルの説明

application.propertiesファイルはデータベースの接続情報設定ファイルです。
どのデータベースを利用するのか、そのアドレス、ユーザ名、パスワードなどの設定を書きます。

```properties:application.properties
##MYSQLを利用する場合
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
##Postgresqlを利用する場合
spring.datasource.driver-class-name=org.postgresql.Driver
##どのデータベースのテーブルを利用するか(MYSQL)
spring.datasource.url=jdbc:mysql://localhost:データベースの数字(初期は3306?)/テーブル名
##Postgresqlを利用する場合
spring.datasource.url=jdbc:postgresql://localhost:5432/DB名
##データベースのユーザ名
spring.datasource.username=ユーザ名
##データベースのパスワード
spring.datasource.password=パスワード
##shema.sqlを実行させる設定
spring.sql.init.mode=always
```

次にschema.sqlではテーブルに関する設定ファイルです。テーブルの作成、削除、テーブルの内容やその他設定をすることができます。

```sql:schema.sql
--起動時、テーブルを削除するコード
DROP TABLE IF EXISTS テーブル名;

--テーブルの作成
CREATE TABLE IF NOT EXISTS table(
    --int型、自動採番、主キーのid
    id INTEGER AUTO_INCREMENT PRIMARY KEY,
    --String型, ユニークなname
    name VARCHAR(255) UNIQUE,
    --DATETIME型, 入力必須な日付
    user_date DATETIME NOT NULL
)
```

次にdata.sqlでは設定したテーブルにデータを追加することができます。

```sql:data.sql
--データの入力
INSERT INTO テーブル名(id, name) VALUES(1, 'Aさん');
```

ここまでが事前に設定するべきファイルです。これらはおそらくどのライブラリを利用していても共通の部分だと思います。

ここからがJDBCTemplateライブラリ独自の設定です。

### 必要なファイル
・Controllerファイル
・データファイル
・DAOファイル
・Serviceファイル
・HTMLファイル
の５つが必要です。

## JDBCTemplateを使ったDB接続
　今回はTODOテーブルにデータを送るという仕組みを作ります。

```SQL:TODOテーブルの作成(schema.sql)
DROP TABLE IF EXISTS todo_table;

CREATE TABLE IF NOT EXISTS todo_table(
    todo_id INTEGER AUTO_INCREMENT PRIMARY KEY,
    todo_content VARCHAR(255) NOT NULL,
    todo_importance INTEGER NOT NULL,
    todo_time TIMESTAMP NOT NULL
);
```

識別するための`todo_id`、TODOの内容の`todo_content`、TODOの重要度を表す`todo_importance`、いつ登録したかを表す`todo_time`という内容を持つテーブルです。

```Java:TodoDao.java
    @Repository
public class TodoDAO {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    public TodoDAO(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void CreateTodo(String todo_content, int todo_importance) {
        //現在時刻を設定する
        Date nowDate = new Date();
        SimpleDateFormat time = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒");
        String formatNowDate = time.format(nowDate);
        String sql = "INSERT INTO todo_table(todo_content, todo_importance, todo_time) values(?, ?, ?)";
        jdbcTemplate.update(sql, todo_content, todo_importance, formatNowDate);
    }
}
```

このクラスはDBに接続してCRUD操作をするクラスです。JDBCTemplteのupdateを使ってINSERTをしています。

```Java:TodoService
@Service
public class TodoService {
    
    private final TodoDAO todoDao;

    @Autowired
    public TodoService(TodoDAO todoDao) {
        this.todoDao = todoDao;
    }
    

    public void createTodo(String todo_content, int todo_importance) {
        todoDao.CreateTodo(todo_content, todo_importance);
    }
}
```

このクラスはTodoDAOを実行するクラスです。

```HTML:TODOを追加するフォーム
<body>
<h1>TODOの追加</h1>
<form th:action="@{/todo_add/add}" th:method="@{get}">
  <label for="todo_content">
    <input type="text" placeholder="やるべきこと" id="todo_content" name="todo_content">
  </label>

  <label for="todo_importance">
    <input type="number" id="todo_importance" placeholder="重要度" name="todo_importance">
  </label>

  <input id="btn" type="submit" value="送信">
</form>
</body>
```

　こちらはSpringのテンプレートエンジンであるThymeleafを利用したものです。
　th:actionでリンクに送信することができます。
  nameタグがControllerの@RequestParamと連携します。
  今回だとnameに`todo_content`を当てていますが、これがControllerの@RequestParam(name="この部分")とつながります。


```Java:Controller
@Controller
public class Controller {
    private final TodoService todoService;

    @Autowired
    public HomeController(TodoService todoService) {
        this.todoService = todoService;
    }

    @GetMapping("/")
    public String addForm() {
        return "TODOを追加するフォーム";
    }

        @GetMapping("/todo_add/add")
    public String add(@RequestParam(name="todo_content") String todo_content,
                      @RequestParam(name="todo_importance") int todo_importance) {
        todoService.createTodo(todo_content, todo_importance);

        return "redirect:/?success";
    }
}
```

　こちらがコントローラです。
 リンク`/`に接続してフォームに接続します。このフォームに値を入力して送信すると`/todo_add/add`に遷移して、フォームからString型の`todo_content`とint型の`todo_importance`を受け取り、TodoServiceのcreateTodoを動かしてDB操作を始めます。そしてリンク`/`に戻るという流れになっています。

 ## まとめ
 　今回の記事はバックエンドの仕事の１つであるDB接続をJDBCTemplateを利用して行ってみました。