表的关联
Belongs To
- belongs to 会与另一个模型建立了一对一的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例
- 例如,您的应用包含 user 和 company,并且每个 user 能且只能被分配给一个 company。下面的类型就表示这种关系。 注意,在 User 对象中,有一个和 Company 一样的 CompanyID。 默认情况下, CompanyID 被隐含地用来在 User 和 Company 之间创建一个外键关系, 因此必须包含在 User 结构体中才能填充 Company 内部结构体
//官方文档
// `User` 属于 `Company`,`CompanyID` 是外键
type User struct {
gorm.Model
Name string
CompanyID int
Company Company
}
type Company struct {
ID int
Name string
}

db.Create(&model.User{
Name: "tracy",
Company: model.Company{
ID: 1,
},
})

关联查询
- 预加载:gorm可以通过Preload、Joins预加载belongs to关联的记录
func PreloadAndJoin(db *gorm.DB) {
var user model.User
db.Preload("Company").First(&user) //preload会执行两条查询语句
var user2 model.User
db.Joins("Company").First(&user2) //join会执行一条查询语句 是left join
fmt.Println(user.Name, user.Company.ID)
fmt.Println(user2.Name, user.Company.ID)
}

belongs To重写外键
- 重写外键:要定义一个 belongs to 关系,数据库的表中必须存在外键。默认情况下,外键的名字,使用拥有者的类型名称加上表的主键的字段名字;例如,定义一个User实体属于Company实体,那么外键的名字一般使用CompanyID
type User struct {
gorm.Model
Name string
CompanyRefer int
Company Company `gorm:"foreignKey:CompanyRefer"` // 使用 CompanyRefer 作为外键 }
type Company struct {
ID int
Name string
}
Has Many
- has many:has many 与另一个模型建立了一对多的连接。 不同于 has one,拥有者可以有零或多个关联模型;例如,您的应用包含 user 和 credit card 模型,且每个 user 可以有多张 credit card
// User 有多张 CreditCard,UserID 是外键
type User struct {
gorm.Model
CreditCards []CreditCard
} type CreditCard struct {
gorm.Model
Number string
UserID uint
}
// Retrieve user list with edger loading credit cards
func GetAll(db *gorm.DB) ([]User, error) {
var users []User
err := db.Model(&User{}).Preload("CreditCards").Find(&users).Error
return users, err
}
Many To Many
- Many To Many:Many to Many 会在两个 model 中添加一张连接表;例如,您的应用包含了 user 和 language,且一个 user 可以说多种 language,多个 user 也可以说一种 language
- 当使用 GORM 的 AutoMigrate 为 User 创建表时,GORM 会自动创建连接表
// User 拥有并属于多种 language,`user_languages` 是连接表
type User struct {
gorm.Model
Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
gorm.Model
Name string
}
自动添加时间
type Language struct {
Name string
AddTime time.Time
//每个记录创建的时候自动加上当前时间加入到AddTime中
}
func (l *Language) BeforeCreate(tx *gorm.DB) (err error) {
l.AddTime = time.Now()
return
}
func main() {
db := Init()
db.Create(&Language{ Name: "python", })
}