ローカル(ホストOS)のJavaプログラムからDockerコンテナ上のMySQLにアクセスする

# はじめに
自分の技術スタックがあまりにもレガシーで情けなく感じ
レガシーおじさんを脱却し、技術者として再出発したく
勉強を始めました。宜しくお願いします&#x1f600;

ということでまずはDockerを勉強することに。

# 構築するもの（今回のゴール）
- 構成図
![MySQL_Dockerトレーニング1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712352/cc5a6164-fe30-6782-33b3-d061bcdf52b4.png)

- ソフトウェア情報
OS：Windows10
Docker：19.03.12
Program：Java11
MySQL：8.0.21
Adminer：latest
WebBrowser：なんでも

とりあえず今回はホストOS上の自前のJavaプログラムから
コンテナ上のDBにアクセスするところからチャレンジ。

# 構築作業
## 1. Dockerコンテナ作成
DockerHubのMySQLの説明ページにあるdocker-compose.ymlをちょっとアレンジして準備。
[DockerHub MySQLページ](https://hub.docker.com/_/mysql)

```yml

# Use root/example as user/password credentials
version: '3.1'

services:

  db:
    image: mysql:8.0.21 #変更
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hoge #追加
      MYSQL_USER: hoge     #追加
      MYSQL_PASSWORD: hoge #追加
    ports:                 #追加
      - 3306:3306          #追加

  adminer:
    image: adminer:latest
    restart: always
    ports:
      - 8080:8080
```
＃が付いてるところがアレンジ部分。
MySQLイメージはlatestを指定するとバージョンがころころ変わりそうな気がしたので8.0.21を指定。
今回はコンテナ外部からアクセスするため、
適当なDBの追加とポート3306を外部公開するように設定。

上記設定ファイルと同階層のフォルダで
docker-composeコマンドで起動。

```
docker-compose up
```
フォアグラウンド実行なのでずらずらログが出るのを見つつ、
別コンソールで立ち上がってるか確認

```
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
0c5d267f22ee        mysql:8.0.21        "docker-entrypoint.s…"   26 seconds ago      Up 25 seconds       0.0.0.0:3306->3306/tcp, 33060/tcp   mysql_db_1
258f5885810d        adminer:latest      "entrypoint.sh docke…"   26 seconds ago      Up 25 seconds       0.0.0.0:8080->8080/tcp              mysql_adminer_1
```
(´・ω・｀)おぉー

## 2. Adminerでテーブル、データ作成
AdminerとはPHPで作られたDB操作できるWebクライアントらしい。
MySQL、Adminerのコンテナが立ち上がってる状態で
http://localhost:8080/
にアクセスすると以下の画面が出るので
さっきのdocker-compose.ymlに記載したDB、ユーザ情報を入れる。
![スクリーンショット 2020-09-16 025707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712352/aab38311-0e27-af9f-d8c9-2de23b67c68a.png)

そしたらこんな感じの適当なテーブルと
![スクリーンショット 2020-09-16 030143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712352/14c6e697-ccd4-02d8-6210-952e3a7d22d8.png)

こんな感じの適当なレコードを入れて、DBは完了。
![スクリーンショット 2020-09-16 030441.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712352/68371788-d726-bc57-b527-90b4775de8d3.png)

## 3. Javaプログラム作成
まずgradleにMySQLドライバの依存関係を記載。

```gradle

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'eclipse'

repositories {
    mavenCentral()}

dependencies {
	compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.21'
    testImplementation 'junit:junit:4.12'
}
```

そしてMySQLにSQLクエリを投げて結果を表示するクラスを作成。

```java
public class DockerMySQLAccessor {

	public static void main(String[] args) {

		System.out.println("DockerコンテナのMySQLにアクセスするよ");

		try(Connection con = DriverManager.getConnection(
			    "jdbc:mysql://localhost:3306/hoge?useSSL=false",
			    "hoge", // UserId
			    "hoge"  // Password
			  )) {

			PreparedStatement pstmt = con.prepareStatement("select * from TEST_TBL");
			ResultSet rs = pstmt.executeQuery();

			while (rs.next()) {
				System.out.printf("ID:%d, HOGE:%s \n", rs.getInt("ID"), rs.getString("HOGE"));
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
```

## 4. 実行
EclipseからさっきのJavaコードを実行。
![スクリーンショット 2020-09-16 032059.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712352/c4367f24-5365-cd90-1efa-590c777aba2f.png)
さっき入れたレコードが取得できてる！
やったぜ。(´・ω・｀)v

# まとめ
とりあえずDockerを使って手軽に仮想的なDBサーバを立ち上げ、
ローカルのプログラムからアクセスすることができた。

今回はDocker触りということで
設定ほぼ丸写しでしかもいきなりdocker-composeの方を使ったけど
実際の運用ではコンテナ毎にDockerfile作ってイメージを作っていくのかな？
あと、プログラムもコンテナ上で実行し、コンテナ間で通信したいところ。
ここら辺はまた今度。

# 謝辞
Win10にDockerを入れるの大いに参考にさせて頂きました。感謝<(_ _)>
[レガシーエンジニアによるDocker入門](https://qiita.com/mamoru12150927/items/5fdab2ac8bb817344291)