GORM多态关联和关联标签详解

一、多态关联

1、多态关联概述

什么是多态?

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。

什么是多态表? 假设我们有一张地址表,其中的地址可能是来自 User 中的,也可能是来自 Orders 中的。而区分不同的对象则用 type 字段。如:type=User 时对象是文章表。

2、为什么用多态关联?

出现需要外键引用多个表的情况,不可能删除原来表结构,重新添加一个外键 ID 再建表,所以我们可以建立一个交叉表。让 Addres 不再依赖于 User 表或者 Order 表。 在这里插入图片描述

has one的情况解决方案,如果我们希望一个给定的地址,只能够在一张交叉表中出现一次,上面的复合主键已经做到了。

has many的情况解决方案,如果希望一个地址可以在一张交叉表中出现多次,可以取消 Address 的复合主键。

3、Has One

GORM 为 has onehas 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值