LoginSignup
2
1

More than 5 years have passed since last update.

Grom入門

Last updated at Posted at 2018-12-17

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で設定できるようにした

2
1
1

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
2
1