Bootstrap

Gorm学习(四)基础:关联

前言

感谢开源项目gin-vue-admin,以及1010工作室的视频教程
本人学识尚浅,如有错误,请评论指出,谢谢!
详细可见个人博客:https://linzyblog.netlify.app/

一、One To One 一对一

数据库连接例子:

var db *gorm.DB

func init() {
   
	var err error
	//我这里用到数据库是mysql,需要配置DSN属性[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
	dsn := "root:123456@tcp(127.0.0.1:3306)/go_test?charset=utf8&parseTime=True"
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
   })
	if err != nil {
   
		panic("failed to connect database")
	}
}

1、Belongs To 属于

belongs to 会与另一个模型建立了一对一的连接。 这种模型的每一个实例都“属于”另一个模型的一个实例。

例如:你有两张表 users 表和 companies 表

  • users --用户表
  • companies --公司表

user 是属于 company 的,就是每个 user 有且只能对应分配给一个 company。

注意:在 User 对象中,有一个和 Company 一样的 CompanyID。 默认情况下, CompanyID 被隐含地用来在 User 和 Company 之间创建一个外键关系, 因此必须包含在 User 结构体中才能填充 Company 内部结构体。


// `User` 属于 `Company`,`CompanyID` 是外键
type User struct {
   
	gorm.Model
	Name      string
	CompanyID int // 默认情况下, CompanyID 被隐含地用来在 User 和 Company 之间创建一个外键关系
	Company   Company
}

type Company struct {
   
	ID   int
	Name string
}

func main() {
   
	//user 里面有 company表的结构 所以只需要自动迁移user表即可
	db.AutoMigrate(&User{
   })
}

在这里插入图片描述

1)创建记录

创建在dachang里的用户linzy的记录

c := Company{
   
	ID:   1,
	Name: "dachang",
}

u := User{
   
	Name:    "linzy",
	Company: c,
}
db.Create(&u)

在这里插入图片描述
在这里插入图片描述

不仅 users 表新增记录,companies 表也新增了。这是因为在创建、更新记录时,GORM 会通过 Upsert 自动保存关联及其引用记录。

2)查询记录

var u User
db.Model(&User{
   }).First(&u)
fmt.Println(u)

在这里插入图片描述

注意:我们发现并没有查出我们关联的 companies 表里面的记录,因为我们在使用CRUD的时候需要所关联的结构时,必须要使用预加载 Preload .

var u User
db.Model(&User{
   }).Preload("Company").First(&u)
fmt.Println(u)

在这里插入图片描述

3)重写外键

要定义一个 belongs to 关系,数据库的表中必须存在外键。默认gorm使用(关联属性类型 + 主键)组成外键名,如上面的例子User + ID 组成UserID,UserID就作为Profile的外键。

例如我们想自定义外键,就需要用标签foreignKe来指定外键:

type User struct {
   
  gorm.Model
  Name         string
  CompanyRefer int
  Company      Company `gorm:"foreignKey:CompanyRefer"`
  // 使用 CompanyRefer 作为外键
}

type Company struct {
   
  ID   int
  Name string
}

4)重写引用

对于 belongs to 关系,GORM 通常使用数据库表,主表(拥有者)的主键值作为外键参考。例如上面的例子,User 中 CompanyRefer 属性作为外键,它和Company 中的ID进行关联,这里 Company 的ID就是关联外键。

我们可以使用标签 references 来更改它,例如:

type User struct {
   
  gorm.Model
  Name      string
  CompanyID string
  Company   Company `gorm:"references:Code"` // 使用 Code 作为引用
}

type Company struct {
   
  ID   int
  Code string
  Name string
}

5)关联模式

a、查找关联

如果我们想查找指定的 user 匹配的关联记录,可以用Association找users表关联的记录:

var user User
db.Where("id = ?", 1).Take(&user)
fmt.Println(user)

var c Company
// `user` 是源模型,它的主键不能为空
// 关系的字段名是 `Company`
// 如果匹配了上面两个要求,会开始关联模式,否则会返回错误
db.Model(&user).Association("Company").Find(&c)
fmt.Println(c)

在这里插入图片描述

b、删除关联

user 可以关联 company,同样也可以不关联,但是去库里删很麻烦,用Delete方法删除源模型与参数之间的关系,只会删除引用,不会从数据库中删除这些对象。

删除前:
在这里插入图片描述

var user User
db.Where("id = ?", 1).First(&user)

//一定要指定关联的主键
db.Model(&user).Association("Company").Delete(&Company{
   ID: 1})

在这里插入图片描述

c、添加关联
var user User
db.Where("id = ?", 1).First(&user)

//一定要指定关联的主键
db.Model(&user).Association("Company").Append(&Company{
   ID: 1}
;