Gorm的关联模型

Belongs To

将一个模型与另一个模型建立一对一的关系

例如:一张银行卡只能分配给一个用户,在User结构体里面创建一个CreditCardId外键关系,然后在User结构体里面嵌套一个CreditCard结构体

// Belongs To
// 用户
type User struct {
    
    
	gorm.Model
	CreditCardId int64
	CreditCard   CreditCard
}
// 银行卡
type CreditCard struct {
    
    
	gorm.Model
	Number string
}

根据结构体创建对应的表结构

db.AutoMigrate(&User{
    
    })

users表:
在这里插入图片描述
credit_cards表:
在这里插入图片描述

插入一条数据

user := User{
    
    
	CreditCardId: 100,
	CreditCard: CreditCard{
    
    
		Number: "123456",
	},
}
db.Create(&user)

users表:
在这里插入图片描述
credit_cards表:
在这里插入图片描述

根据id查询一条数据

需要使用预加载,否则嵌套结构体里面的内容将不会被查询出来

var user User
err = db.Preload("CreditCard").Where("id=?", 1).Find(&user).Error
if err != nil {
    
    
	fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)

注意:在对表进行删除的时候应该先删除父表(users表),再删除子表(credit_cards)

Has One

同样的,Has One也是用来建立一对一的关系,这种关联表明一个模型的每个实例都包含或拥有另一个模型的一个实例。与Belongs To不同的是,外键的位置是在嵌套结构体的内部

// Has One
// 用户
type User struct {
    
    
	gorm.Model
	CreditCard CreditCard
}
//银行卡
type CreditCard struct {
    
    
	gorm.Model
	Number string
	UserID int64
}

根据结构体创建对应表结构

db.AutoMigrate(&User{
    
    }, &CreditCard{
    
    })

users表:
在这里插入图片描述
credit_cards表
在这里插入图片描述

插入一条数据

关于结构体的内容,属性是gorm.model的内容时不必进行赋值,由于CreditCard属于内部嵌套结构体,所以UserID无需指定,值是User结构体的ID值

user := User{
    
    
	CreditCard: CreditCard{
    
    
		Number: "100",
	},
}
db.Create(&user)

users表
在这里插入图片描述
credit_cards表
在这里插入图片描述

查询数据仍然需要使用预加载

var user User
err = db.Preload("CreditCard").Where("id=?", 1).Find(&user).Error
if err != nil {
    
    
	fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)

Has Many

Has Many将一个模型与另一个模型建立一对多的关系,嵌套结构体是一个切片类型,而在嵌套内部结构体将通过一个id保证与外部结构体的关系
银行卡的例子说明,每一个人可以拥有很多张银行卡,但是每张银行卡都有对应属于自己的id值

// Has Many
type User struct {
    
    
	gorm.Model
	CreditCards []CreditCard
}

type CreditCard struct {
    
    
	gorm.Model
	Number string
	UserID int64
}

根据结构体创建对应表结构

建表的时候与Has One键的表一样

db.AutoMigrate(&User{
    
    }, &CreditCard{
    
    })

插入一条数据

user := User{
    
    
	CreditCard: []CreditCard{
    
    
		{
    
    Number: "100"}, {
    
    Number: "101"}, {
    
    Number: "101"},
	},
}
db.Create(&user)

对应users表,创建一个一个用户,对用credit_cards表,将创建三条银行卡数据

查询数据需要使用预加载

var user User
err = db.Preload("CreditCards").Where("id=?", 1).Find(&user).Error
if err != nil {
    
    
	fmt.Printf("err: %v\n", err)
}
fmt.Printf("user: %v\n", user)

Many To Many

Many to Many 会在两个 model 中添加一张连接表

例如:在一个大小合适中的关系网中,一个人可以有多个群聊,每个群聊都有多个不同的人。

type User struct {
    
    
	gorm.Model
	ChatGroups []ChatGroup `gorm:"many2many:user_chat_group;"`
}
type ChatGroup struct {
    
    
	gorm.Model
	Name  string
	Users []User `gorm:"many2many:user_chat_group;"`
}

根据结构体创建对应表结构

db.AutoMigrate(&User{
    
    })

使用User结构体将创建三个表users表,chat_groups表,user_chat_group

插入一条数据

var user = User{
    
    
	ChatGroups: []ChatGroup{
    
    
		{
    
    Name: "幸福一家人"}, {
    
    Name: "研究生小分队"}, {
    
    Name: "钓鱼佬永不空军"},
	},
}
db.Create(&user)

users表
chat_groups表
关系对应表

对于第一次插入数据,没有指定的id将被自动赋值,默认升序,第二次插入数据:新建一个用户id=2,用户的群聊是id等于1,2的两个群聊

var user = User{
    
    
	Model: gorm.Model{
    
    
		ID: 2,
	},
	ChatGroups: []*ChatGroup{
    
    
		{
    
    
			Model: gorm.Model{
    
    
				ID: 1,
			},
		},
		{
    
    
			Model: gorm.Model{
    
    
				ID: 2,
			},
		},
	},
}
db.Create(&user)

此时,users表中添加一条数据,chat_groups表中没有新数据插入,user_chat_group对应关系表中插入两条数据
对应关系表

查询数据

var user User
//查询指定用户,并且预加载用户的群聊信息
db.Preload("ChatGroups").Where("id=?", 1).Find(&user)
fmt.Printf("user: %v\n", user)

var chats []ChatGroup
//查询指定群聊,并且预加载群聊里面的人
db.Preload("Users").Where("id=?", 1).Find(&chats).Association("ChatGroup")
fmt.Printf("chats: %v\n", chats)

关于预加载,是将该结构体中的一个嵌套结构体属性值填入Preload中,注意不是预加载的表名称,不是预加载的结构体名称,而是对应的嵌套结构体名字

数据删除

根据用户id删除用户信息,并且把用户关联表的对应数据也删除

删除users表中的用户信息,同时也删除用户群聊对应表user_chat_group中所有的用户信息

user := User{
    
    
   Model: gorm.Model{
    
    
      ID: 2,
   },
   ChatGroups: []ChatGroup{
    
    
      {
    
    
         Model: gorm.Model{
    
    
            ID: 1,
         },
      },
      {
    
    
         Model: gorm.Model{
    
    
            ID: 2,
         },
      },
   },
}
db.Select("ChatGroups").Delete(&user)

修改数据

根据用户id修改用户信息,并且把用户关联表的对应数据也修改

例如,一个用户的群聊从原来的id=1,2群,变更成为id=2,3群

user := User{
    
    
    Model: gorm.Model{
    
    
        ID: 2,
    },
}
chats := []ChatGroup{
    
    
    {
    
    
        Model: gorm.Model{
    
    
            ID: 2,
        },
    },
}
db.Model(&user).Association("ChatGroups").Replace(&chats)

猜你喜欢

转载自blog.csdn.net/m0_58121644/article/details/130274251
今日推荐