僕なりの Go 備忘録

# GoとGinのDocker環境を作る

```bash
.
├── Dockerfile
├── docker-compose.yml
└── www
    ├── app
    │   ├── go.mod
    │   ├── go.sum
    │   ├── main.go
    │   └── views
    │       └── index.html
    └── html
```

```yaml
# docker-compose.yml
version: '3'

services:
  go:
    build:
      context: .
      dockerfile: Dockerfile
    stdin_open: true
    tty: true
    volumes:
      - ./www:/var/www
    ports:
      - 8080:8080
```

```dockerfile
# Dockerfile
FROM golang:1.22.4-bullseye

WORKDIR /var/www/app
```

```go
// main.go
package main

import (
  "github.com/gin-gonic/gin"
)

func main() {
  router := gin.Default()
  router.LoadHTMLGlob("./views/*.html")

  router.GET("/", func(ctx *gin.Context){
    ctx.HTML(200, "index.html", gin.H{})
  })

  router.Run()
}
```

image,containerを作る

```bash
$ docker-compose build
$ docker-compose up -d
```

ginを入れる

```bash
$ docker-compose exec go bash
$ go mod init hoge
$ go get github.com/gin-gonic/gin
```

main.goを実行（時間掛かる、、、）

```bash
$ go run main.go
```

確認

```bash
$ curl http://localhost:8080
# or
http://localhost:8080 にアクセス
```



# go installとgo get

## go install

`go install` コマンドは、指定されたパッケージをコンパイルして、その実行可能ファイルを `$GOPATH/bin` ディレクトリ（または `GOBIN` 環境変数で指定されたディレクトリ）にインストールする。

ローカルの作業ディレクトリや、Goモジュールが有効な場合はそのモジュールの依存関係にあるパッケージを対象に使用できる。

`go install` はGo 1.17から、特にモジュールモードで使用する際の推奨される方法となり、外部のパッケージをインストールする際にも依存関係の管理を行う。



## go get

`go get` コマンドは、Go 1.16以前では外部パッケージをダウンロードし、必要に応じてインストールするために広く使用されていた。

指定されたパッケージをダウンロードし、それを `$GOPATH/src` に配置し、パッケージが依存する他のパッケージも同時に取得する。

Go 1.17以降、モジュールモードがデフォルトとなったため、`go get` は依存関係の追加や更新、特定のパッケージのバージョン指定のために使用されることが多くなった。

また、Go 1.17以降では `go install` が推奨される方法となっており、`go get` は主に依存関係の管理に使われるようになった。

`-u`: 指定されたパッケージが既にインストールされている場合に、最新のバージョンにアップデートする。



# gorm

Goで書かれたアプリケーションがMySQLデータベースを使用する際に非常に重要。

GORMライブラリは、データベースの操作を簡素化し、データをGoの構造体としてマッピングすることで、データベースのCRUD（作成、読み取り、更新、削除）操作を直感的かつ効率的に行えるように支援する。

`gorm.io/driver/mysql` パッケージは、GORMライブラリを通じてMySQLデータベースとやり取りするための具体的な実装を提供する。したがって、このドライバをプロジェクトに追加することで、MySQLデータベースを利用したアプリケーション開発が可能になる。





### dsn := "root@tcp(mysql:3306)/first?charset=utf8mb4&parseTime=True&loc=Local"

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

//DB接続
dsn := "root@tcp(mysql:3306)/first?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
    panic("failed to connect database")
}
```

- DSN (Data Source Name)

    : この文字列は、データベースへの接続情報を含んでいる：

    - **ユーザー名**: `root`
    - **プロトコルとホスト**:
        -  `tcp(mysql:3306)` ここで、`mysql` はDockerコンポーズで設定されたMySQLサービスのホスト名と見なされ、ポート番号は `3306` 。
        -  **tcp**: ここで使われている `tcp` は、Transmission Control Protocolの略で、インターネットプロトコルスイートの一部である通信プロトコル。データベースへの接続において `tcp` を指定することで、信頼性の高い接続が確立され、データの正確な転送が保証される。
        -  **mysql**: この部分はホスト名。Dockerを使用する場合、`mysql` はDocker Composeファイルで定義されたMySQLサービスのサービス名と一致している必要がある。Docker Composeではサービス間の通信を容易にするために、サービス名をDNS名として使用できるように内部的なネットワーキングを提供する。つまり、`mysql` という名前でサービスが定義されている場合、他のサービスからはその名前を使用してアクセスできる。
        -  **3306**: これはMySQLのデフォルトのポート番号。ポート番号は、サーバ上の特定のサービスにアクセスするために使われる番号で、MySQLは通常ポート3306をリッスンする。
    - **データベース名**: `first`
    - その他のオプション：
        - `charset=utf8mb4`: 文字セットとして `utf8mb4` を使用。
        - `parseTime=True`: 日時データをGoのtime.Time型に自動変換。
        - `loc=Local`: タイムゾーンをローカルタイムゾーンに設定。