gorm中的外键问题

476 阅读2分钟

外键约束

1、belong to

1.不带tag的方式,默认使用参考表的主键,并使用填充内部结构的字段名字加上ID(UserID)为外键

 // 不定义foreignKey 外键 和 references 引用
 type User1 struct {
     gorm.Model
     Name string
     Age  int
 }
 type Comment1 struct {
     gorm.Model
     Title   string
     Content string
     User    User1
     // UserID 和 UserId 都可以
     UserID uint
 }
 ​
 func BelongTo1() {
     db := DB
 ​
     db.AutoMigrate(
         &User1{},
         &Comment1{},
     )
 }

image-20240611142448354.png 2.带tag的方式 既指定外键和引用

需要注意引用的字段需要拥有索引

 // 自定义foreignKey 外键 和 references 引用
 type User2 struct {
     //若不带gorm.Model 会报错
     gorm.Model
     Name string
     Age  int `gorm:"index:idx_age,unique"`
 }
 type Comment2 struct {
     gorm.Model
     Title   string
     Content string
     User    User2 `gorm:"foreignKey:UserAge;references:Age"`
     // UserID 和 UserId 都可以
     UserAge int
 }
 ​
 func BelongTo2() {
 ​
     DB.AutoMigrate(
         &User2{},
         &Comment2{},
     )
 }

image-20240611143526456.png

2、has one

 // User3 有一张 CreditCard,UserID 是外键
 // 若是数字结尾则表名称在创建时不加s
 type User3 struct {
     gorm.Model
     CreditCard CreditCard `gorm:"foreignKey:UserID"`
 }
 ​
 type CreditCard struct {
     gorm.Model
     Number string
     UserID uint
 }
 ​
 // HasOne1
 func HasOne1() {
 ​
     DB.AutoMigrate(
         &User3{},
         &CreditCard{},
     )
 }

image-20240612004734645.png

3.has many

 // 若是数字结尾则表名称在创建时不加s
 type User4 struct {
     gorm.Model
     CreditCards2 []CreditCard2 `gorm:"foreignKey:UserRefer"`
 }
 ​
 type CreditCard2 struct {
     gorm.Model
     Number    string
     UserRefer uint
 }
 ​
 // HasMany
 func HasMany() {
 ​
     DB.AutoMigrate(
         &User4{},
         &CreditCard2{},
     )
 }

image-20240612005300846.png

4.many to many

1.一个结构体包含many2many标签的情况

 // User 拥有并属于多种 language,`user_languages` 是连接表
 type User5 struct {
     gorm.Model
     Languages []Language1 `gorm:"many2many:user_languages;"`
 }
 ​
 type Language1 struct {
     gorm.Model
     Name string
 }
 ​
 // ManyToMany
 func ManyToMany1() {
 ​
     DB.AutoMigrate(
         &User5{},
         &Language1{},
     )
 }

连接表user_languages结构为

 user_languages | CREATE TABLE `user_languages` (
   `user5_id` bigint unsigned NOT NULL,
   `language1_id` bigint unsigned NOT NULL,
   PRIMARY KEY (`user5_id`,`language1_id`),
   KEY `fk_user_languages_language1` (`language1_id`),
   CONSTRAINT `fk_user_languages_language1` FOREIGN KEY (`language1_id`) REFERENCES `language1` (`id`),
   CONSTRAINT `fk_user_languages_user5` FOREIGN KEY (`user5_id`) REFERENCES `user5` (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

2.两个结构体都拥有many2many标签的情况

 // User 拥有并属于多种 language,`user_languages` 是连接表
 type User6 struct {
     gorm.Model
     Languages []*Language2 `gorm:"many2many:user_languages2;"`
 }
 ​
 type Language2 struct {
     gorm.Model
     Name  string
     Users []*User6 `gorm:"many2many:user_languages2;"`
 }
 ​
 // ManyToMany2
 func ManyToMany2() {
 ​
     DB.AutoMigrate(
         &User6{},
         &Language2{},
     )
 }

与上述建表情况一样,但是应该在代码中使用有所有区别