Webアプリの開発環境からデータベースに接続できるようにする

# 前書き

https://qiita.com/gengen0719/items/bcdda4b8571f5e687051

この記事はこちらの記事の続き。
せっかくなのでデータベースを利用できるようにする。

# データベースの準備

## Dockerデスクトップのインストール

Docker Desktop for Windowsを押してインストーラーをダウンロードしてインストール。

https://docs.docker.com/desktop/install/windows-install/

## MySQLのDocker imageを取得する
```
docker pull mysql
```

## Docker Imageの起動
```
docker run --name testdb -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=testdb -P --expose=3306 -p 3306:3306 -d mysql:latest
```
- データベースの名前は `testdb`
- データベースのrootユーザーのパスワードは `root`
- データベース接続の際のPortは `3306`
- 利用するMySQLDBのイメージは最新のもの

## DBeaverのインストール
作成したデータベースに接続するため、DBeaverを準備する。

Windows(installer)をクリックしてダウンロードし、インストールする。

https://dbeaver.io/download/

## DBeaverの設定
データベースナビゲーターの中で右クリック、作成、接続を押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/6652ab32-3c05-7edd-a8b4-3ea8199b7afa.png)

MYSQLを選択し、次へボタンを押す。
Server Host : `localhost`
Port : `3306`
Database : `testdb` 
ユーザー名 : `root`
パスワード : `root`

テスト接続ボタンを押して、接続されることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/b4970158-9bb2-a28c-bb90-adbc62fefb28.png)

接続されたらOKボタンを押す。[^1]

[^1]:`Public Key Retrieval is not allowed` エラーが発生する場合は `ドライバのプロパティ` から `allowPublicKeyRetrieval` を `TRUE` にして再度試す。
ただしTLSで保護されていない通信での接続を許可するものであるため、あくまでも開発用の設定変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/1182f7f0-ea46-9f66-36b1-3995067032ed.png)

接続したtestdbのプルダウンをクリックして、データベース、testdbを開き右クリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/91c8d6cc-6ae4-58ad-79cd-0b52bcd1633b.png)

SQLエディタ、SQLエディタを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/3e327b1f-3f79-681f-ab83-6825cdd19b67.png)

New scriptをクリックし、SQLエディタを表示する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/3942b693-1104-b1be-9c04-7b0343405316.png)

ここにSQLを入力して `SQL文を実行する` を押すことでSQLが実行できます。

## データベースにテーブルを作成する
```SQL
CREATE TABLE TEST(
 MESSAGE VARCHAR(255)
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/3ec2407e-7642-97b1-c2fc-2bc32ca512b1.png)


## 作成したテーブルにデータを投入する
```SQL
INSERT INTO TEST VALUES ("テストメッセージ！！！");
```


## 投入したデータの確認
```SQL
SELECT * FROM TEST
```

実行すると新しいウインドウが開き、実行結果が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/b51f167a-5fd9-ac0d-607c-937d88444fc8.png)

# アプリからデータベースに接続して動かす

build.graldeの `dependencies` にMySQLのドライバとSpringJDBCを追記。

```gradle
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
    runtimeOnly 'com.mysql:mysql-connector-j'
    implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
}
```

追記するとGradleが必要なライブラリを取得してくれます。


application.propertiesにデータベースへの接続情報を追記。[^2]

[^2]:あくまでも実験のためrootユーザーで接続。アプリケーションとしてリリースするのであれば適切な権限を設定したユーザーを作成し、そのユーザーで接続する。

```
spring.application.name=demo
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
```

前回動かしてみた[Controllerとhtml](https://qiita.com/gengen0719/items/bcdda4b8571f5e687051#%E5%8B%95%E3%81%8B%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)を改造し、データベースから取得したメッセージを画面に表示する。

DemoController
```Java
package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class DemoController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("test")
    public String getMethodName(Model model) {
        String sql = "SELECT MESSAGE FROM TEST";
        String message = jdbcTemplate.queryForObject(sql, String.class);
        model.addAttribute("message", message);
        return "test";
    }
    
}
```

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

<p style="color:red;" th:text="${message}"></p>
```

http://localhost:8080/test にアクセス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/e063054c-0fb1-7e9b-d29a-108bf5de3d0b.png)

DBの値を変更すると表示されるメッセージも変化する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/b1241ff6-97f3-f2b0-eaab-58fa6bc947ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1126770/010e71a1-60f2-c2a5-b612-37e80f965e8e.png)

おわり。

追記：

この記事で準備した開発環境のクラスを分割し、SpringのDIの仕組みを使ってインジェクションする記事を書きました。

https://qiita.com/gengen0719/items/65cab20943bf4cce61ca

更にSpringSecurityを使ってログインの仕組みを実装する記事を書きました。

https://qiita.com/gengen0719/items/e442feb2c322d633ab63

ご興味あればこちらもご覧ください。