SQLへの繋ぎ方(mySQL)



## やること
Dockerでdbサーバを立てて、そこにアプリケーション上からアクセスする

### Dockerでdbサーバを立てる
今回はMySQLを使用(理由はなんとなく)
```yml:docker-compose.yml
version: '3'

services:
  db:
    image: mysql:5.7
    environment: 
    - MYSQL_DATABASE=sample_db
    - MYSQL_ROOT_PASSWORD=password
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
    ports:
      - 3306:3306
```
と記述した。
その後、この`docker-compose.yml`があるディレクトリで、
```
$ docker-compose up -d
```
を実行して、コンテナを起動する。
コンテナが起動できているかどうか確認するには、
```shell
$ docker ps
または
$ docker-compose ps
```
で確認でき、`NAMES`や`NAME`に`(ディレクトリ名)-db-1`とあれば、今回作成したコンテナが起動できているとわかる。

### dbにアプリケーション上からアクセスする
今回はgolangのgormを使ってアクセスする。
今回のアプリケーションのディレクトリ構造は以下のようなものにした。
```gormSample
.
├── controllers
│   ├── controlles.go
│   └── init.go
├── docker-compose.yml
├── go.mod
├── go.sum
├── main.go
└── model
    └── type.go
```
(ディレクトリの分け方については勉強できていないので、勘です。)

まず、gormを使ってdbに接続します。
```golang: controllers/init.go
package controllers

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func DbInit() *gorm.DB {
	parseTime=true
	dsn := "root:password@tcp(localhost:3306)/sample_db?charset=utf8mb4&parseTime=true"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		panic(err)
	}

	return db
}
```
また、gormは構造体でテーブルにカラムを生成してくれるので、構造体を用意する。
``` go: model/type.go
package model

import "gorm.io/gorm"

type User struct {
	gorm.Model

	Name     string
	Age      int
	IsActive bool
}
```
この`User`という構造体をもとに、DBを作る。

``` go: main.go
package main

import (
	"github.com/39shin52/gormsample/controllers"
	"github.com/39shin52/gormsample/model"
)

func main() {
	db := controllers.DbInit()

	db.AutoMigrate(&model.User{})
}
```
`AutoMigrate`というものが、構造体をもとにテーブルを自動的に生成してくれる。便利。

### この後
このあとは、よしなにInsert(Create)の機能やSELECT(Read)の機能を実装すれば、dbを自由に自由に弄ることが出来る！
ちなみに、本当にデータ追加されてる？とか気になった時は、コンテナ内を見に行く。
``` shell
$ docker-compose exec -it CONTAINER ID /bin/bash
bash-4.2\# mysql -u root -p
> Enter password: (passwordと出てこないけど打ち込む)
> Welcome to the MySQL monitor...
> ...
mysql> show databases;
> +--------------------+
> | Database           |
> +--------------------+
> | information_schema |
> | mysql              |
> | performance_schema |
> | sample_db          |
> | sys                |
> +--------------------+ 
mysql> use sample_db;
> Database changed
mysql> show tables;
> +---------------------+
> | Tables_in_sample_db |
> +---------------------+
> | users               |
> +---------------------+
mysql> select * from users;
> +----+-------------------------+-------------------------+------------+--------+------+-----------+
> | id | created_at              | updated_at              | deleted_at | name   | age  | is_active |
> +----+-------------------------+-------------------------+------------+--------+------+-----------+
> |  1 | 2022-11-27 00:00:00.000 | 2022-11-27 00:00:00.000 | NULL       | Tanaka |   20 |         1 |
> |  2 | 2022-11-27 00:00:00.000 | 2022-11-27 00:00:00.000 | NULL       | Sato   |   22 |         0 |
> +----+-------------------------+-------------------------+------------+--------+------+-----------+
```
上に書いたのは、Insertしたあとなので、一番最初に`main.go`を実行したときは、何も入ってないよみたいなこと言われます。

## 参考にさせていただいた記事
https://zenn.dev/a_ichi1/articles/4b113d4c46857a

https://qiita.com/ponsuke0531/items/df51a784b5ff48c97ac7

https://qiita.com/petertakahashi/items/debebac6e5ad16bd069c