試したリポジトリはここ。
https://github.com/ritarock/sandbox/tree/master/golang/sample_gorm
gorm.Open(dialect string, args ...interface{})
の第一引数は接続するデータベース、第二引数には接続情報。
今回は Docker で実行したのでコンテナが起動しても mysql は起動していない場合があったので 30 秒待つ処理を入れた。
func gormConnect() *gorm.DB {
DBMS := "mysql"
PROTOCOL := "tcp(db:3306)"
USER := "user"
PASS := "password"
DBNAME := "app"
CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?parseTime=true"
var err error
db, err := gorm.Open(DBMS, CONNECT)
if err != nil {
fmt.Println("Not ready")
time.Sleep(time.Second)
count++
if count > 30 {
panic(err.Error())
}
return gormConnect()
}
fmt.Println("Success connect")
return db
}
構造体を定義する。
フィールドの ID
は gorm では主キーとなる。 CreatedAt
と UpdatedAt
はレコードの作成時と更新時に自動的で設定される。
type Post struct {
ID int
Content string
Author string `sql:"not null"`
Comments []Comment
CreatedAt time.Time
}
type Comment struct {
ID int
Content string
Author string `sql:"not null"`
PostId int
CreatedAt time.Time
}
gorm ではフィールドタグ gorm:""
を設定すること制約などの設定を行える。
設定できるものは ここ を参照。
User は Company に所属している。
type User struct {
gorm.Model
Name string
CompanyID int
Company Company
}
type Company struct {
ID int
Name string
}
別のモデルと 1 対 1 の関係。
type User struct {
gorm.Model
CreditCard CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
User は CreditCard を複数持っている。
type User struct {
gorm.Model
CreditCards []CreditCard
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
Book は複数の Author を持ち、 Author は複数の本を持っている。
type Book struct {
gorm.Model
Authors []Author `gorm:"many2many:author_books"`
}
type Author struct {
gorm.Model
Books []Book `gorm:"many2many:author_books"`
}
足りないカラムの追加、変更、インデックスの作成は行うが、不要になったカラムの削除等は行われない。
db.AutoMigrate(&Post{}, &Comment{})