MyDocs

# GolangのORM試した

試したリポジトリはここ。

https://github.com/ritarock/sandbox/tree/master/golang/sample_gorm

DB に接続

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 では主キーとなる。 CreatedAtUpdatedAt はレコードの作成時と更新時に自動的で設定される。

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:"" を設定すること制約などの設定を行える。

設定できるものは ここ を参照。

belongs to

User は Company に所属している。

type User struct {
  gorm.Model
  Name      string
  CompanyID int
  Company   Company
}

type Company struct {
  ID   int
  Name string
}

has one

別のモデルと 1 対 1 の関係。

type User struct {
  gorm.Model
  CreditCard CreditCard
}

type CreditCard struct {
  gorm.Model
  Number string
  UserID uint
}

has many

User は CreditCard を複数持っている。

type User struct {
  gorm.Model
  CreditCards []CreditCard
}

type CreditCard struct {
  gorm.Model
  Number string
  UserID uint
}

many to many

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{})