一、多态关联
1、多态关联概述
什么是多态?
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。
什么是多态表? 假设我们有一张地址表,其中的地址可能是来自 User 中的,也可能是来自 Orders 中的。而区分不同的对象则用 type 字段。如:type=User 时对象是文章表。
2、为什么用多态关联?
出现需要外键引用多个表的情况,不可能删除原来表结构,重新添加一个外键 ID 再建表,所以我们可以建立一个交叉表。让 Addres 不再依赖于 User 表或者 Order 表。
has one
的情况解决方案,如果我们希望一个给定的地址,只能够在一张交叉表中出现一次,上面的复合主键已经做到了。
has many
的情况解决方案,如果希望一个地址可以在一张交叉表中出现多次,可以取消 Address 的复合主键。
3、Has One
GORM 为 has one
和 has many
提供了多态关联支持,它会将拥有者实体的表名、主键值都保存到多态类型的字段中。
type User struct {
ID int
Name string
//polymorphic指定多态类型,比如模型名
Address Address `gorm:"polymorphic:Owner;"`
}
type Order struct {
ID int
Name string
Address Address `gorm:"polymorphic:Owner;"`
}
type Address struct {
ID int
Name string
OwnerID int
OwnerType string
}
func main() {
db.AutoMigrate(User{
}, Order{
}, Address{
})
}

db.Create(User{
Name: "linzy",
Address: Address{
Name: "翻斗花园",
},
})
db.Create(Order{
Name: "忘崽牛奶",
Address: Address{
Name: "火星幼儿园",
},
})
owner_type 就是关联的那张表。 owner_id 就是关联的表的主键。
4、Has Many
type User struct {
ID int
Name string
Address []Address `gorm:"polymorphic:Owner;"`
}
type Order struct {
ID int
Name string
Address Address `gorm:"polymorphic:Owner;"`
}
type Address struct {
ID int
Name string
OwnerID int
OwnerType string
}
func main() {
db.AutoMigrate(User{
}, Order{
}, Address{
})
db.Create(User{
Name: "linzy",
Address: []Address{
{
Name: "翻斗花园"},
{
Name: "杭州西湖"},
},
})
}
二、关联标签
1、polymorphic polymorphicValue
type User struct {
ID int
Name string
//polymorphic:通俗讲用来指定id与type的前缀
Address []Address `gorm:"polymorphic:Address;"`
}
type Order struct {
ID int
Name string
//polymorphicValue用来告诉关联表我是谁,默认都是表名
Address Address `gorm:"polymorphic:Address;polymorphicValue:master"`
}
type Address struct {
ID int
Name string
AddressID int
AddressType string
}
func main() {
db.AutoMigrate(User{
}, Order{
}, Address{
})
db.Create(User{
Name: "linzy",
Address: []Address{
{
Name: "翻斗花园"},
{
Name: "杭州西湖"},
},
})
db.Create(Order{
Name: "忘崽牛奶",
Address: Address{
Name: "火星幼儿园",
},
})
}
2、foreignKey references
GORM 里默认是连接表和引用表的主键来作为做外键以及外键映射的。
Has One 的例子:
type CreditCard struct {
gorm.Model
Number string
//外键指向CreditCardNumber
Info Info `gorm:"foreignKey:CreditCardNumber"`
}
type Info struct {
ID uint
Name string
Age int
CreditCardNumber string