Day08:GORM快速入门06 属于| 青训营

101 阅读4分钟

导读

本套笔记是学习完Gin框架之后的下一个阶段,通过Gin框架我们可以很方便的和前端进行交互,下一步就是和数据库进行交互,这就需要使用GORM。本套笔记就是带你快速上手GORM,学习完这个之后就可以完成大项目的开发了,后续还会进行大项目的讲解开发,制作不易,喜欢的就点个关注吧。

本套课程基于GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.进行讲解,是对这个的补充解释说明。

注意

代码详解大部分是注释的形式给出,请留意代码注释。

GORM介绍

GORM(Go Object Relational Mapping)是一个在 Go 语言中使用的优秀的 ORM(对象关系映射)库。它提供了简单且强大的 API,使开发人员能够轻松地与数据库进行交互

Belongs To

在 GORM 中,Belongs To 是一种定义模型之间关系的方式,表示一个模型属于另一个模型。

package main  
  
import (  
"gorm.io/driver/mysql"  
"gorm.io/gorm"  
)  
  
// 父级结构体  
type Parent struct {  
ID uint `gorm:"primaryKey"`//主键  
Name string `gorm:"column:name"`//指定了数据库表中对应的列名为 `name`  
}  
  
// 子级结构体  
type Child struct {  
ID uint `gorm:"primaryKey"` //主键  
Name string `gorm:"column:name"` //指定了数据库表中对应的列名为 `name`  
ParentID uint `gorm:"column:parent_id"` // 表示 Child 模型属于 Parent 模型  
Parent Parent `gorm:"foreignKey:ParentID"`  //表示 `Child` 模型的 `ParentID` 字段作为外键与 `Parent` 模型建立关联
}  
  
func main() {  
  
db, _ := gorm.Open(mysql.New(mysql.Config{  
DSN: "root:Lycdemima1@@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local", // DSN data source name  
DefaultStringSize: 256, // string 类型字段的默认长度  
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持  
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引  
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列  
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置  
}), &gorm.Config{}) //连接数据库  
  
db.AutoMigrate(&Parent{}, &Child{})//自动建表  
  
parent := Parent{Name: "John"}  
db.Create(&parent)  
  
child := Child{Name: "Alice", ParentID: parent.ID}  
db.Create(&child)  
  
}

运行之后表关系是这样的

image.png image.png

外键

要定义一个 belongs to 关系,数据库的表中必须存在外键

外键的名字,使用拥有者的类型名称加上表的主键的字段名字

例如,定义一个User实体属于Company实体,那么外键的名字一般使用CompanyID

重写外键

gorm:"foreignKey:"用于自定义外键,也可以重写外键

package main  
  
import (  
"fmt"  
"gorm.io/driver/mysql"  
"gorm.io/gorm"  
)  
  
type Parent struct {  
ID uint `gorm:"primaryKey"`  
Name string `gorm:"column:name"`  
}  
  
type Child struct {  
ID uint `gorm:"primaryKey"`  
Name string `gorm:"column:name"`  
CustomParentID uint `gorm:"column:custom_parent_id"`  
Parent Parent `gorm:"foreignKey:CustomParentID"`//重写外键  
}  
  
func main() {  
  
db, err := gorm.Open(mysql.New(mysql.Config{  
DSN: "root:Lycdemima1@@tcp(127.0.0.1:3306)/test?charset=utf8&parseTime=True&loc=Local", // DSN data source name  
DefaultStringSize: 256, // string 类型字段的默认长度  
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持  
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引  
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列  
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置  
}), &gorm.Config{}) //连接数据库  
  
err = db.AutoMigrate(&Parent{}, &Child{})  
if err != nil {  
panic("Failed to migrate database")  
}  
  
parent := Parent{Name: "John"}  
result := db.Create(&parent)  
if result.Error != nil {  
panic("Failed to create parent")  
}  
  
child := Child{Name: "Alice", CustomParentID: parent.ID}  
result = db.Create(&child)  
if result.Error != nil {  
panic("Failed to create child")  
}  
  
fmt.Println("Parent and child created successfully")  
  
}

运行之后表关系

image.png

image.png

重写引用

对于 belongs to 关系,GORM 通常使用数据库表,主表(拥有者)的主键值作为外键参考。 正如上面的例子,我们使用主表Company中的主键字段ID作为外键的参考值。

如果设置了User实体属于Company实体,那么GORM会自动把Company中的ID属性保存到User的CompanyID属性中。

以下是示例代码,展示了如何在 GORM 中使用 references 标签定义外键引用的列名:

type Child struct {
	ID           uint   `gorm:"primaryKey"`
	Name         string `gorm:"column:name"`
	ParentID     uint   `gorm:"column:parent_id"`
	Parent       Parent `gorm:"foreignKey:ParentID;references:ID"`
}

我们通过 gorm:"column:parent_id"ParentID 作为外键列名,并使用 references:ID 来指定外键引用的列名为 ID

外键约束

在 GORM 中,可以使用 constraint 标签来指定外键约束的名称和行为

type Child struct {
	ID           uint   `gorm:"primaryKey"`
	Name         string `gorm:"column:name"`
	ParentID     uint   `gorm:"column:parent_id;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
	Parent       Parent `gorm:"foreignKey:ParentID"`
}

OnUpdate:CASCADE 表示在父表主键更新时,子表的外键会自动更新;OnDelete:SET NULL 表示在父表主键删除时,子表的外键会被设置为 NULL 值