关于GORM外键失效问题 一

本文详细探讨了GORM中设置外键和处理表关系的方法,包括一对一、一对多和多对多关系的配置。对于一对一关系,通过特定字段命名实现外键关联;一对多关系需在主从结构体上设置外键和切片字段;多对多关系则利用中间表自动创建关联。作者还分享了测试总结和注意事项,帮助读者理解GORM的数据库迁移策略。
摘要由CSDN通过智能技术生成

先聊聊Gorm外键的设置:

我个人比较喜欢tag直接设置,但今天做项目就出了问题,tag一直失效。但找不到原因在哪里。网上的答案只有用AddForeignKey方法去手动添加外键。但我想搞清楚为什么tag会失效

关于tag的设置,在gorm中有如下几个设置:

MANY2MANY                             指定连接表
FOREIGNKEY                            设置外键
references                            指定引用的表中的字段
ASSOCIATION_FOREIGNKEY                设置当前表中关联的外键字段
POLYMORPHIC                           指定多态类型
POLYMORPHIC_VALUE                     指定多态值
JOINTABLE_FOREIGNKEY                  指定连接表的外键
ASSOCIATION_JOINTABLE_FOREIGNKEY      指定连接表的关联外键
SAVE_ASSOCIATIONS                     是否自动完成 save 的相关操作
ASSOCIATION_AUTOUPDATE                是否自动完成 update 的相关操作
ASSOCIATION_AUTOCREATE                是否自动完成 create 的相关操作
ASSOCIATION_SAVE_REFERENCE            是否自动完成引用的 save 的相关操作
PRELOAD                               是否自动完成预加载的相关操作

 表与表之间的关系也就那么三个:

  • 一对一:个人和身份证
  • 多对一:学生对班级
  • 多对多:学生对老师

 针对不同的情况,GORM对不同的表关系做了不同的策略

一对一:

        我们可以如下设置:

type Staff struct {
	ID            int
	Name          string  `gorm:"primaryKey"`    //实际测试,Company123Name也可以当自动外键
	Company123ID  int     //默认外键,gorm约定:连接companies表id字段		目标表名+ID   (这个'ID'是固定的,不是当前或目标的主键字段,目标表名可以有任意前缀,不影响)
	Company123    Company /*`gorm:"embedded"`*/ //该字段在创建时,会被忽略。除非有embedded字段,表示嵌套。会初始化company表的不重复字段
}

type Company struct {
	ID   int
	Name string			`gorm:"primaryKey"`    //测试外键是否会连接主键
	CompanyAge int
}

我测试了好多次,有如下总结:

一对一关系的设置时,从结构体有主结构体的复杂字段(如Staff中有Company类型字段)

并根据默认外键的约定:同时有该字段名+当前表主键名的字段(或ID)会被当作外键去跟主结构体主键关联

一对多:


type Student struct {
	ID	string
	ClassId string
	Class Class
	Name string
	//Teachers []Teacher		`gorm:"many2many:stu_tea"`
}

//一对多关系:一个班级中有多个学生
type Class struct {
	ID int
	Students []Student	`gorm:"FOREIGNKEY:ClassId;"`
}

    一对多的关系设置时,主结构有从结构的切片复杂字段 

其次需要从结构要有外键字段,这时根据默认外键约定 ,我们需要两步

1.在从结构添加主结构复杂字段,以满足默认外键约定

2.在主结构的切片字段上添加tag:FOREIGNKEY:从结构字段 以指定外键字段

我们可以通过1,来达成反向搜索的目的

多对多:

type Student struct {
	ID	string
	//ClassId string
	//Class Class
	Name string
	Teachers []Teacher		`gorm:"many2many:stu_tea"`
}

//多对多:老师跟学生多对多的关系
type Teacher struct {
	ID string
	Name string
	Students []Student		`gorm:"many2many:stu_tea"`
}

感动哭了,多对多的关系是最简单的。

1.我们需要在俩结构中各放一个外表的切片字段

2.其次我们需要给该字段(任意一个)设置gorm:"many2many:中间表名"

当我们通过        db.AutoMigrate() 方法去迁移数据库时,gorm会自动创建一个中间表,来自动关联两表

最后,虽然这些问题看起来比较简单,但整理起来也很花时间。最重要的是不断求知的思考过程,愿我们都能前程似锦

参考:GORM-学习 - 掘金 (juejin.cn)但其关于外键部分结论是有错误的,论证如上,版本问题?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值