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ファイルを作成
[Database]
driver = "mysql"
server = ""
user = "hoge"
password = ""
database = "hoge"
charset = "utf8"
parseTime = "true"
db用の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が代入される
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の更新)にしてくれる
まとめソース
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で設定できるようにした