Day08:GORM快速入门08 many to many| 青训营

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Day08:GORM快速入门08 many to many| 青训营

导读

本套笔记是学习完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,使开发人员能够轻松地与数据库进行交互

many to many

Many to Many 会在两个 model 中添加一张连接表,将不同表的id连接起来

例如:您的应用包含了 user 和 language,且一个 user 可以说多种 language,多个 user 也可以说一种 language。

// User 拥有并属于多种 language,`user_languages` 是连接表
type User struct {
  gorm.Model
  Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
  gorm.Model
  Name string
}

当使用 GORM 的 AutoMigrateUser 创建表时,GORM 会自动创建连接表

完整代码

package main  
import (  
"fmt"  
"gorm.io/driver/mysql"  
"gorm.io/gorm"  
"log"  
)  
type User struct {  
gorm.Model  
Languages []Language `gorm:"many2many:user_languages;"`  
}  
type Language struct {  
gorm.Model  
Name string  
}  
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(&User{}, &Language{})  
if err != nil {  
log.Fatal(err)  
}  
// 创建用户及关联的语言  
err = CreateUserWithLanguages(db, "john", "English")  
if err != nil {  
log.Fatal(err)  
}  
// 查询用户及关联的语言  
user, err := GetUserWithLanguages(db, 1)  
if err != nil {  
log.Fatal(err)  
}  
fmt.Println("User:", user)  
fmt.Println("Languages:")  
for _, lang := range user.Languages {  
fmt.Println(lang)  
}  
}  
func CreateUserWithLanguages(db *gorm.DB, username string, languageName string) error {  
language := Language{  
Name: languageName,  
}  
user := User{  
Languages: []Language{language},  
}  
result := db.Create(&user)  
return result.Error  
}  
func GetUserWithLanguages(db *gorm.DB, userID uint) (User, error) {  
var user User  
result := db.Preload("Languages").First(&user, userID)  
return user, result.Error  
}

表关系如图

image.png

image.png

image.png

连接池绑定他们的id

重写外健

对于 many2many 关系,连接表会同时拥有两个模型的外键,例如

type User struct {
  gorm.Model
  Languages []Language `gorm:"many2many:user_languages;"`
}
type Language struct {
  gorm.Model
  Name string
}

若要重写它们,可以使用标签 foreignKeyreferencesjoinforeignKeyjoinReferences。当然,您不需要使用全部的标签,你可以仅使用其中的一个重写部分的外键、引用。

type User struct {
    gorm.Model
    Profiles []Profile `gorm:"many2many:user_profiles;foreignKey:Refer;joinForeignKey:UserReferID;References:UserRefer;joinReferences:ProfileRefer"`
    Refer    uint      `gorm:"index:,unique"`
}
type Profile struct {
    gorm.Model
    Name      string
    UserRefer uint `gorm:"index:,unique"`
}

自引用

type User struct {
  gorm.Model     
  Friends []*User `gorm:"many2many:user_friends"` 
}

会创建连接表:user_friends

走定义连接池

type Person struct {
  ID        int
  Name      string
  Addresses []Address `gorm:"many2many:person_addressses;"`
}
type Address struct {
  ID   uint
  Name string
}
type PersonAddress struct {
  PersonID  int `gorm:"primaryKey"`
  AddressID int `gorm:"primaryKey"`
  CreatedAt time.Time
  DeletedAt gorm.DeletedAt
}
func (PersonAddress) BeforeCreate(db *gorm.DB) error {
  // ...
}
// 修改 Person 的 Addresses 字段的连接表为 PersonAddress
// PersonAddress 必须定义好所需的外键,否则会报错
err := db.SetupJoinTable(&Person{}, "Addresses", &PersonAddress{})
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
Go 数据库
Go语言之GORM框架(四)——预加载,关联标签与多态关联,自定义数据类型与事务(完结篇)
Go语言之GORM框架(四)——预加载,关联标签与多态关联,自定义数据类型与事务(完结篇)
279 0
|
Go
Golang的time.NewTimer单次定时器使用案例
这篇文章介绍了Go语言中time包的多种定时器使用案例,包括单次定时器的创建、阻塞程序运行的Sleep函数、重置和停止定时器的方法,以及After和AfterFunc函数的使用。
240 5
Golang的time.NewTimer单次定时器使用案例
|
计算机视觉 异构计算
【YOLOv8改进-SPPF】 AIFI : 基于注意力的尺度内特征交互,保持高准确度的同时减少计算成本
YOLOv8专栏介绍了该系列目标检测框架的最新改进与实战应用。文章提出RT-DETR,首个实时端到端检测器,解决了速度与精度问题。通过高效混合编码器和不确定性最小化查询选择,RT-DETR在COCO数据集上实现高AP并保持高帧率,优于其他YOLO版本。论文和代码已开源。核心代码展示了AIFI Transformer层,用于位置嵌入。更多详情见[YOLOv8专栏](https://blog.csdn.net/shangyanaf/category_12303415.html)。
|
PHP 开发者
深入理解PHP7的返回类型声明
【5月更文挑战第27天】 在PHP7中,引入了一项新的语言特性——返回类型声明。这一功能允许开发者在函数定义时明确指定函数应返回的数据类型,从而提升代码的可读性和健壮性。本文将深入探讨返回类型声明的概念、用法以及其对现有PHP项目的影响,旨在为PHP开发者提供一份详细的技术解析和实践指南。
|
Go 数据安全/隐私保护
Golang:使用标准库crypto/aes实现AES加密和解密
Golang:使用标准库crypto/aes实现AES加密和解密
1638 0
|
JSON 虚拟化 Docker
Windows10 Docker安装和docker-compose 安装
Windows10 Docker安装和docker-compose 安装
1368 0
|
小程序 安全 JavaScript
微信小程序授权登录--流程讲解
微信小程序授权登录--流程讲解
1441 0
|
SQL 分布式计算 关系型数据库
Hive-安装与配置(1)
Hive-安装与配置(1)
1391 0
|
分布式计算 资源调度 Kubernetes
大数据问题排查系列 - SPARK STANDALONE HA 模式的一个缺陷点与应对方案
大数据问题排查系列 - SPARK STANDALONE HA 模式的一个缺陷点与应对方案
|
人工智能 并行计算 PyTorch
【AI 大模型】离线运行ChatGLM2-6B(清华大模型)
【AI 大模型】离线运行ChatGLM2-6B(清华大模型)
2502 0

热门文章

最新文章