6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Go言語(Golang)でMySQLを使ったAPIを作成する

Posted at

#まえがき
APIを作るにあたって大規模の同時接続に対応させたいと考え,
PythonのDjangoで作成していたAPIをGolangで作成し直すことにした。

なかなか思い通りに動かせず,つまづいた点が多くあったので記録に残す。

PythonでGoのパフォーマンスに勝てるかを検証する

#Goの環境設定

Goダウンロード

// 確認
% go version
go version go1.16.2 darwin/amd64

// 環境情報
% go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/akidon/Library/Caches/go-build"
GOENV="/Users/akidon/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/akidon/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/akidon/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.16.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/akidon/program/go/goAPI/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/qg/6f_bf3fx4qs2gxwzhbc_pks00000gn/T/go-build311814080=/tmp/go-build -gno-record-gcc-switches -fno-common"

// PATH追加
% open ~/.zshrc

以下を追加

a.zshrc
#Goのパス
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOROOT/bin:$PATH
export PATH=$GOPATH/bin:$PATH

動作確認

適当なフォルダにhello.goというファイルを作成して、Visual Studio Codeで下記のように編集。

package main

import "fmt"

func main() {
    fmt.Println("Hello!");
}

ターミナルで先ほどのフォルダに移動して、 go run hello.go コマンドを実行。「Hello!」と表示されれば成功。

% go run hello.go
Hello!

#Goのパッケージ
Echo ... RestfullAPIの作成(他にもGinやGorillaなどがある)
Gorm ... MySQLを操作するため

もし以下のエラーが出れば
cannot find package "github.com/hoge"
go get github.com/hoge すればよい

% go mod init go-tools

% go get github.com/labstack/echo
% go get github.com/jinzhu/gorm
% go get github.com/joho/godotenv

MySQLをダウンロード

Mac 初期設定 備忘録
からMySQLをダウンロード

% mysql.server start 
// mysql.server stop でサーバー停止

# MySQLに入る
% mysql -u root
# アカウント作成
mysql> create user 'ユーザー名'@'localhost' identified by 'パスワード';

# データベース作成('golang'というDBを作成)
mysql> create database golang;

# 作成したアカウントに権限を追加
mysql> GRANT ALL ON golang.* TO 'ユーザー名'@'localhost';

mysql> exit;

SequelAceを使うとMySQLの操作が楽
SequelAceダウンロード

GolangからMySQLのデータを追加・更新・取得

##MySQL側
テーブル名 users

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| golang             |  <- 作成
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

mysql> use golang;
mysql> show tables;
+------------------+
| Tables_in_golang |
+------------------+
| users            |
+------------------+

mysql> desc users;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int unsigned | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | YES  |     | NULL    |                |
| age         | int          | YES  |     | NULL    |                |
| created_at  | timestamp    | YES  |     | NULL    |                | <- 必要
| updated_at  | timestamp    | YES  |     | NULL    |                | <- 必要
| deleted_at  | timestamp    | YES  |     | NULL    |                | <- 必要
+-------------+--------------+------+-----+---------+----------------+

スクリーンショット 2021-04-04 13.15.48.png

SequelAceを使ってこの様に作成した
Gormを使う際[created_at,updated_at,deleted_at]を作成しておく必要がある

##Golang側

gormを使用してMySQLを操作しようとしたが,つまずいた。
原因は詳しくは理解できていないが,命名が間違っていたっぽい。
大文字,小文字,複数,単数に注意して命名する必要があった。
MySQLではusersだが,Golangで呼び出すときは"User"
MySQLではnameだが,Golangで呼び出すときは"Name"
など注意が必要。

確認動作チャックはしていないのでエラーが出る可能性があります

main.go
package routing

import (
	"fmt"
	"github.com/labstack/echo"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

type User struct {
	gorm.Model
    //`json:"--"`はリクエストボディに指定する名前
	Name                string `json:"name"`
	Age                 int    `json:"age"`
}


func (u User) String() string {
	return fmt.Sprintf("Name:%s \n Age:%d \n ",
		u.Name,
		u.Age)
}

// ユーザーを登録,更新
func BaseAPI_user() echo.HandlerFunc {
	return func(c echo.Context) error {
		db := databases.GormConnect()
		defer db.Close()

		//リクエストボディ
		user := new(User)

		user1 := User{
			Name:     user.Name,
			Age:      user.Age,}

		// 追加
		insertUsers := []User{user1}
		insert(insertUsers, db)

		// 更新
		update(user1, db)

		// 検索(年齢一致)
		var count = search(user.Age, db)

		return c.JSON(200, count)
	}
}

func insert(users []User, db *gorm.DB) {
	for _, user := range users {
		db.NewRecord(user)
		db.Create(&user)
	}
}

func update(users User, db *gorm.DB) {
	var user User
	db.Model(&user).Where("id = ?", 1).Update(map[string]interface{}{"name": users.Name, "Age": users.Age})
}


func search(age int, db *gorm.DB) ([]User) {
	var user []User
	db.Raw("SELECT * FROM users WHERE age = ? ", age).Scan(&user)

	return user
}

// SQLConnect DB接続
func GormConnect() (database *gorm.DB) {
	// パスワード等を.envファイルから読み取る
	// program > go > .env
	err := godotenv.Load(fmt.Sprintf("../%s.env", os.Getenv("GO_ENV")))
	if err != nil {
		panic(err.Error())
	} else {
		fmt.Println("env読み取り成功")
	}

	DBMS := "mysql"                   // MySQL
	PROTOCOL := "tcp(localhost:3306)" // db:3306
	DBNAME := ""    // テーブル名
	USER := ""      // MySQLユーザー名
	PASS := ""  // パスワード

	CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo"
	db, err := gorm.Open(DBMS, CONNECT)
	if err != nil {
		panic(err.Error())
	} else {
		fmt.Println("DB接続成功")
	}
	return db
}
6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?