Edited at

Grom入門


Gormとは

Go言語で扱うORMライブラリのひとつ

Gormにはマイグレーション機能もついている


公式ドキュメント

ここを読み込めばだいたいわかる

http://gorm.io/ja_JP/docs/


導入方法

Go言語の機能のgo getコマンドを使ってインストールする

go get -u github.com/jinzhu/gorm

MySQLのドライバーをインストール

go get github.com/go-sql-driver/mysql

設定ファイルをtomlというファイルで設定するためインストール

※tomlである必要はないが今回はtomlで設定

go get -u github.com/BurntSushi/toml


接続方法

config.tomlファイルを作成


db.toml

[Database]

driver = "mysql"
server = ""
user = "hoge"
password = ""
database = "hoge"
charset = "utf8"
parseTime = "true"

db用のgoファイルを作成


main.go

package main

import (
"fmt"

"github.com/BurntSushi/toml"
_ "github.com/jinzhu/gorm/dialects/mysql"
)

type DbConfig struct {
Driver string
Server string
User string
Password string
Database string
Charset string
ParseTime string
}

type Config struct {
Database DbConfig
}

func (d DbConfig) DSN() string {
return fmt.Sprintf("%s:%s@%s/%s?charset=%s&parseTime=%s", d.User, d.Password, d.Server, d.Database, d.Charset, d.ParseTime)
}

func (c Config) Db() (string, string) {
return c.Database.Driver, c.Database.DSN()
}

func GetConfig() Config {
var config Config
_, err := toml.DecodeFile("config.toml", &config)
if err != nil {
panic("unloaded config file")
}

return config
}


以下の処理で db に接続されたDBが代入される


main.go

var db *gorm.DB

func init() {
var err error
config := GetConfig()

db, err = gorm.Open(config.Db())
if err != nil {
panic(err.Error())
}
}



使い方


準備

go 言語にはクラスがないのでstructにモデルデータを記述

適当にAccountモデルを作成

go では 変数名 型 の順で宣言

type Account struct {

ID int
Name string
Email string
Address string
}

以下の関数を呼び出すとstructに定義された要素のテーブルを作成してくれる

db.AutoMigrate(&Product{})


Tips

変数名は頭文字大文字のキャメルケースで

頭文字が大文字でないとAutoMigrateが機能しない

structに定義した名称の複数形で作成される(Account → Accounts)

カラムの削除などについては以下を参照

http://gorm.io/ja_JP/docs/migration.html

gorm.Modelをstructに加えると以下の要素を加えることができる

これによって論理削除を簡単に実装できる

type Model struct {

ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}

元のAccountがカラム数が4だったのに

Account(id, name, email, address)

type Account struct {

ID int
Name string
Email string
Address string
}

gorm.Modelを加えるとカラム数が7になる

Account(id, created_at, updated_at, deleted_at, name, email, address)

type Account struct {

gorm.Model
Name string
Email string
Address string
}

参照方法は直下に変数があるように扱う

    account := Account{}

db.First(&account)

// gorm.Model
fmt.Println(account.ID)
fmt.Println(account.CreatedAt)
fmt.Println(account.UpdatedAt)
fmt.Println(account.DeletedAt)

// 自作変数
fmt.Println(account.Name)
fmt.Println(account.Email)
fmt.Println(account.Address)

詳しくは以下を参照

http://gorm.io/ja_JP/docs/conventions.html


操作(CRUD)


Create

CreateとNewRecordの2つの関数がある

NewRecord

プライマリキーが重複していてもエラーにならない(処理は実行されない)

account := Account{Name: "Jinzhu", Address: "tokorozawa"}

db.NewRecord(account)

Create

参照を渡す、プライマリキーが重複しているとエラーになる

account := Account{Name: "Jinzhu", Address: "tokorozawa"}

db.Create(&account)

その他詳細は以下

http://gorm.io/ja_JP/docs/create.html


Query

例を書くより公式の方がわかりやすいので

http://gorm.io/ja_JP/docs/query.html


Tips

全レコードの取得

db.Find([]&user) // 全レコード

DeletedAtを持っているstructでdeleted_atに値が入っている場合、勝手にselectから除外してくれる

実行クエリの確認

db.Debug().Where("id = ?", accountID).Find(&account)

dbの後にDebugをつける

Firstでは使えないみたい


Update

例を書くより公式の方が〜

http://gorm.io/ja_JP/docs/update.html


Delete

db.Delete(&email)

例を書くより〜

http://gorm.io/ja_JP/docs/delete.html


Tips

プライマリキーが代入されていない場合、 全てのレコード が削除される

DeletedAtを持っているstructでdeleted_atに値が入っている場合、勝手に物理削除ではなく論理削除(deleted_atの更新)にしてくれる


まとめソース


main.go

package main

import (
"fmt"

mydb "./db"
"github.com/BurntSushi/toml"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)

type Account struct {
gorm.Model
Email string
Address string
Name string
}

var db *gorm.DB

func main() {
// create
fmt.Println("create")
account := Account{Name: "Jinzhu", Address: "tokorozawa"}
db.Create(&account)

// query
fmt.Println("")
fmt.Println("query")
account2 := Account{}
db.First(&account2)
fmt.Println(account2.ID)
fmt.Println(account2.Name)
fmt.Println(account2.CreatedAt)

// update
fmt.Println("")
fmt.Println("update")
account2.Address = "utsunomiya"
db.Save(&account2)

account3 := Account{}
db.First(&account3)
fmt.Println(account3.Address)

// delete
fmt.Println("")
fmt.Println("delete")
db.Delete(&account3)

account4 := Account{}
db.First(&account4)
fmt.Println(account4.ID)
}

func init() {
var err error
config := mydb.GetConfig()

db, err = gorm.Open(config.Db())
if err != nil {
panic(err.Error())
}
db.AutoMigrate(&Account{})

}

type DbConfig struct {
Driver string
Server string
User string
Password string
Database string
Charset string
ParseTime string
}

type Config struct {
Database DbConfig
}

func (d DbConfig) DSN() string {
return fmt.Sprintf("%s:%s@%s/%s?charset=%s&parseTime=%s", d.User, d.Password, d.Server, d.Database, d.Charset, d.ParseTime)
}

func (c Config) Db() (string, string) {
return c.Database.Driver, c.Database.DSN()
}

func GetConfig() Config {
var config Config
_, err := toml.DecodeFile("config.toml", &config)
if err != nil {
panic("unloaded config file")
}

return config
}


以下で実行

init → main の順で実行される

go run main.go

結果

create

query
3
Jinzhu
2018-12-17 07:17:25 +0000 UTC

update
utsunomiya

delete
0


参考サイト様

【GORM】Go言語でORM触ってみた

gormで実行されているクエリ(SQL文)を確認する

GORMの接続情報をtomlで設定できるようにした