Skip to content

Instantly share code, notes, and snippets.

@shionryuu
Created October 27, 2014 11:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shionryuu/00385f4959884386ac72 to your computer and use it in GitHub Desktop.
Save shionryuu/00385f4959884386ac72 to your computer and use it in GitHub Desktop.
gorm模型定义

gorm模型定义

示例

type User struct {
    Id           int64
    Birthday     time.Time
    Age          int64
    Name         string  `sql:"size:255"`
    CreatedAt    time.Time
    UpdatedAt    time.Time
    DeletedAt    time.Time

    Emails            []Email         // One-To-Many relationship (has many)
    BillingAddress    Address         // One-To-One relationship (has one)
    BillingAddressId  sql.NullInt64   // Foreign key of BillingAddress
    ShippingAddress   Address         // One-To-One relationship (has one)
    ShippingAddressId int64           // Foreign key of ShippingAddress
    IgnoreMe          int64 `sql:"-"` // Ignore this field
    Languages         []Language `gorm:"many2many:user_languages;"` // Many-To-Many relationship, 'user_languages' is join table
}

type Email struct {
    Id         int64
    UserId     int64   // Foreign key for User (belongs to)
    Email      string  `sql:"type:varchar(100);"` // Set field's type
    Subscribed bool
}

type Address struct {
    Id       int64
    Address1 string         `sql:"not null;unique"` // Set field as not nullable and unique
    Address2 string         `sql:"type:varchar(100);unique"`
    Post     sql.NullString `sql:not null`
}

type Language struct {
    Id   int64
    Name string
}

注意: - 1.需要反射的字段、外键必须导出 - 2.可以通过类型、命名、标签(tag)指定属性、关系

标签

tag 之间空格分隔,tag 选项之间用分号(;)分隔

sql标签

- type:value      类型,`sql:"type:varchar(100);"`
- not null        不为空,`sql:"not null"`
- unique          唯一,`sql:"not null;unique"`
- default:value   默认值,`sql:"default:0"`
- size:value      大小,`sql:"size:255"`
- \-              忽略该字段,`sql:"-"`

参见:utils.go parseTagSetting/1; scope_private.go sqlTagForField/1

gorm标签

- many2many:table_name      多对多映射,table_name是关联的表名
- column:name               该字段在数据库表中的字段名
- foreignkey:               一对多和多对多关系默认struct名+"Id",一对一关系存在两个默认值
- associationforeignkey:    仅用于一对多和多对多关系,默认Slice元素类型名+"Id"
- embedded                  嵌入的类型,和匿名类型一样需要递归处理
- primary_key               主键,默认'Id'字段为主键

参见:scope.go fieldFromStruct/2

关系

- 一对一关系         字段类型为struct(time.Time、sql.Scanner结构除外,下同)
    - belongs_to     外键保留在本结构中(上面的User.BillingAddressId),SaveBeforeAssociations/1中处理约束
    - has_one        外键保留在字段对应的struct中,SaveAfterAssociations/1中处理约束
- 一对多关系         字段类型为未指定many2many的[]struct
    - has_many
- 多对多关系         字段类型为指定many2many的[]struct
    - many_to_many

参见:scope.go fieldFromStruct/2

外键约束

- 一对一关系:
    - 通过foreignkey指定,如果存在foreignkey指定字段,则为belongs_to类型;否则为has_one类型
    - 未指定foreignkey,belongs_to类型为字段类型名+"Id"的字段(上面的User.BillingAddressId);has_one类型,外键为struct名+"Id"
- 一对多关系:外键为一类型struct名+"Id",关联外键为该Slice元素类型名+"Id"(注:非many2many的情况下,如果在多类型结构中找不到该外键,则外键为空)
- 多对多关系:同一对多

参见:scope.go fieldFromStruct/2; callback_shared.go SaveBeforeAssociations/1, SaveAfterAssociations/1

约束处理

- SaveBeforeAssociations/1 插入当前结构前调用,先插入关联的数据,然后用关联数据的primary key更新外键
- SaveAfterAssociations/1  插入当前结构后调用
    - has_one关系用primary key更新关联数据的外键并插入关联数据
    - has_many关系且外键可以在关联结构中找到,用primary key更新关联数据的外键并插入关联数据
    - many_to_many关系用primary key更新关联数据的外键并插入关联数据 或者 many2many选项存在时更新关联表

参见:callback_shared.go SaveBeforeAssociations/1, SaveAfterAssociations/1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment