概要

現在Golangを学習しています。その中でMySQLとの接続に詰まってしまったのでその解決方法を共有したいと思います。

前提

私は基本的に学習するときはローカルの環境を汚したくないのでDockerを使用しています。
なので今回もDockerを使用して行います。
なお今回は、Dockerの構成を最低限しか設定しません。

Dockerfile構成

FROM golang:1.19.0-alpine3.16
WORKDIR /app
COPY . .

docker-compose.yml構成

version: '3.9'
services:
  db:
    image: mysql:8.0
    container_name: mysql
    env_file: .env
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DB_NAME}
    volumes:
      - ./mysql:/var/db/mysql
  web:
    build:
      context: .
    container_name: web
    volumes:
      - .:/app
    depends_on:
      - db
volumes:
  mysql:

詰まった部分

今回詰まったところは、Go側からMySQLへの接続部分です。

下記のように設定ファイルを記載し、Ping()を利用し接続を確認しました。

package models

import (
	"database/sql"
	"fmt"
	"log"

	"github.com/soicchi/golang-todo-app/config"

	_ "github.com/go-sql-driver/mysql"
)

var Db *sql.DB

var err error

func init() {
	connectionInfo := fmt.Sprintf("root:%s@/%s", config.Config.Password, config.Config.DbName)
	Db, err = sql.Open(config.Config.SQLDriver, connectionInfo)
	if err != nil {
		log.Fatalln(err)
	}

	err = Db.Ping()
	if err != nil {
		log.Fatalln(err)
	}
	log.Println("データベース接続完了")
}

上記のコードを呼び出すために簡易的に下記のようにmain.goからグローバル変数Dbを呼び出してみます。

package main

import (
	"fmt"

	"github.com/soicchi/golang-todo-app/app/models"
)

func main() {
	fmt.Println(models.Db)
}

すると下記のようなエラーが返ってきました。

2022/08/13 12:17:15 base.go:30: dial tcp 127.0.0.1:3306: connect: connection refused

どうやら接続できていないようです。

解決方法

下記の記事を参考にするとDockerを使用している場合、接続情報にdocker-compose.ymlで定義したコンテナ名を入れないといけないらしい。

 

つまり、先ほどのapp/models/base.goを下記のように変更しないといけません。

package models

import (
	"database/sql"
	"fmt"
	"log"

	"github.com/soicchi/golang-todo-app/config"

	_ "github.com/go-sql-driver/mysql"
)

var Db *sql.DB

var err error

func init() {
	connectionInfo := fmt.Sprintf("root:%s@tcp(mysql)/%s", config.Config.Password, config.Config.DbName) // root:%s@/%s → root:%s@tcp(mysql)/%sに変更
	Db, err = sql.Open(config.Config.SQLDriver, connectionInfo)
	if err != nil {
		log.Fatalln(err)
	}

	err = Db.Ping()
	if err != nil {
		log.Fatalln(err)
	}
	log.Println("データベース接続完了")
}

もう一度main.goを実行してみると

2022/08/13 12:19:39 base.go:32: データベース接続完了
&{0 0x40000a8058 0 {0 0} [0x4000226000] map[] 0 1 0x400008e0c0 false map[0x4000226000:map[0x4000226000:true]] map[] 0 0 0 0 <nil> 0 0 0 0 0xbf060}

無事接続されました。

まとめ

今回はDockerを使用したことで接続に手間取ってしまいましたが、
それでもDockerはかなり便利なので手放せないですね(笑)
間違った指摘があるようでしたら、是非ともご指摘いただけると幸いです。
最後まで閲覧していただきありがとうございました。

广告
将在 10 秒后关闭
bannerAds