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 选项之间用分号(;)分隔
- 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
- 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