导读
本套笔记是学习完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,使开发人员能够轻松地与数据库进行交互
实体关联
实体关联是数据库设计中的一个概念,用于描述不同实体之间的关系和连接。它定义了实体之间的相互作用、依赖和关联方式,使得数据可以以一定结构和规则进行组织和访问。
在实体关联中,通常有两个或多个实体之间存在某种形式的连接或关系。这些关系可以是一对一、一对多或多对多等。
这些我们在前面都已经介绍过了。
自动创建、更新
一个用户可以发表多篇文章
package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) type User struct { gorm.Model Name string Articles []Article } //user结构体 type Article struct { gorm.Model Title string Content string UserID uint User User } //article结构体 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(&User{}, &Article{}) //创建表 // 创建用户和文章,并建立关联 user := User{Name: "John"} db.Create(&user) article := Article{Title: "Hello", Content: "World", UserID: user.ID} db.Create(article) // 查询用户及其关联的文章 var fetchedUser User db.Preload("Articles").First(&fetchedUser, user.ID) fmt.Println("User:", fetchedUser) fmt.Println("Articles:") for _, article := range fetchedUser.Articles { fmt.Println(article) } }
我们先把表结构创建好
数据库如图,可以看到id那些都自动的写好了
之后我们更新一下
// 更新文章内容 fetchedUser.Articles[0].Content = "Updated Content" result = db.Save(&fetchedUser.Articles[0])
成功更新内容
关联模式
查找关联
查找所有匹配的关联记录
db.Model(&user).Association("Languages").Find(&languages)
查找带条件的关联
codes := []string{"zh-CN", "en-US", "ja-JP"} db.Model(&user).Where("code IN ?", codes).Association("Languages").Find(&languages) db.Model(&user).Where("code IN ?", codes).Order("code desc").Association("Languages").Find(&languages)
添加关联
为 many to many
、has many
添加新的关联;为 has one
, belongs to
替换当前的关联
db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Append(&Language{Name: "DE"}) db.Model(&user).Association("CreditCard").Append(&CreditCard{Number: "411111111111"})
替换关联
用一个新的关联替换当前的关联
db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Replace(Language{Name: "DE"}, languageEN)
删除关联
如果存在,则删除源模型与参数之间的关系,只会删除引用,不会从数据库中删除这些对象。
db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN}) db.Model(&user).Association("Languages").Delete(languageZH, languageEN)
清空关联
删除源模型与关联之间的所有引用,但不会删除这些关联
db.Model(&user).Association("Languages").Clear()
关联计数
返回当前关联的计数
db.Model(&user).Association("Languages").Count() // 条件计数 codes := []string{"zh-CN", "en-US", "ja-JP"} db.Model(&user).Where("code IN ", codes).Association("Languages").Count()
批量处理数据
// 查询所有用户的所有角色 db.Model(&users).Association("Role").Find(&roles) // 从所有 team 中删除 user A db.Model(&users).Association("Team").Delete(&userA) // 获取去重的用户所属 team 数量 db.Model(&users).Association("Team").Count() // 对于批量数据的 `Append`、`Replace`,参数的长度必须与数据的长度相同,否则会返回 error var users = []User{user1, user2, user3} // 例如:现在有三个 user,Append userA 到 user1 的 team,Append userB 到 user2 的 team,Append userA、userB 和 userC 到 user3 的 team db.Model(&users).Association("Team").Append(&userA, &userB, &[]User{userA, userB, userC}) // 重置 user1 team 为 userA,重置 user2 的 team 为 userB,重置 user3 的 team 为 userA、 userB 和 userC db.Model(&users).Association("Team").Replace(&userA, &userB, &[]User{userA, userB, userC})
常用标签
标签 | 描述 |
foreignKey | 指定当前模型的列作为连接表的外键 |
references | 指定引用表的列名,其将被映射为连接表外键 |
polymorphic | 指定多态类型,比如模型名 |
polymorphicValue | 指定多态值、默认表名 |
many2many | 指定连接表表名 |
joinForeignKey | 指定连接表的外键列名,其将被映射到当前表 |
joinReferences | 指定连接表的外键列名,其将被映射到引用表 |
constraint | 关系约束,例如:OnUpdate 、OnDelete |