Golang gorm
GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.
一 对多入门
比如要开发cmdb的系统,无论是硬件还是软件。硬件对应的就是对应的哪个开发在用。或者服务对应的是哪个业务模块在使用,或者应用谁在使用。那么这就是一对多的关系。
has many介绍
- has many 关联就是创建和另一个模型的一对多关系(数据库里面是一对多,然后struct里面也是一对多)
- 例如, 例如每一个用户都拥有多张信用卡,这样就是生活中一个简单的一对多关系

在设计表的时候不可能将所有的信息都放在一个表里面,那么表就会非常非常的宽。这样字段就会非常的多,性能就会受到影响。
在设计的时候这里其实就可以设置为两张表。一个是用户的详情表和信用卡的详情表,用户表里面加上卡的id和他做一个关联,那么这就是一对多的关系。
当一个数据库存储了很多数据的时候就需要分库分表,上面也类似,将一张表分为两张表。
creditcar的外键是userid。
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {gorm.Model //默认创建三个时间字段和一个id字段,create_at update_at delete_at这样可以知道创建时间/更新时间/删除时间CreditCards []*CreditCard66
}//用户有多张信用卡,UserID是外键
type CreditCard struct {gorm.ModelNumber stringUserId int //默认会在CreditCard表中生成User66Id字段作为与user表关联的外键id//默认会在CreditCard表中生成UserID字段作为与User表关联的外键ID
}func main() {dsn := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn66), &gorm.Config{})db.AutoMigrate(User{}, CreditCard{})
}
mysql> show tables;
+-------------------+
| Tables_in_test_db |
+-------------------+
| credit_cards |
| users |
+-------------------+
2 rows in set (0.00 sec)mysql> desc users;
+------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
+------------+-----------------+------+-----+---------+----------------+mysql> desc credit_cards;
+------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| number | bigint | YES | | NULL | |
| user_id | bigint unsigned | YES | MUL | NULL | |
+------------+-----------------+------+-----+---------+----------------+mysql> drop table users;
ERROR 3730 (HY000): Cannot drop table 'users' referenced by a foreign key constraint 'fk_users_credit_cards' on table 'credit_cards'.
二 外键
type User struct{gorm.ModelCreditCards []CreditCard `gorm:"foreignKey:UserRefer"`
}type CreditCard struct{gorm.ModelNumber stringUserRefer uint
}
`gorm:"foreignKey:UserRefer"` 可以使用这个字段来去改它的外键。
import ("gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {gorm.ModelCreditCards []*CreditCard `gorm:"foreignKey:UserRefer"`
}type CreditCard struct {gorm.ModelNumber intUserRefer int
}func main() {dsn6 := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn6), &gorm.Config{})db.AutoMigrate(&User{}, &CreditCard{})
}mysql> desc users;
+------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
+------------+-----------------+------+-----+---------+----------------+mysql> desc credit_cards;
+------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| number | bigint | YES | | NULL | |
| user_refer | bigint unsigned | YES | MUL | NULL | |
+------------+-----------------+------+-----+---------+----------------+mysql> drop tables users;
ERROR 3730 (HY000): Cannot drop table 'users' referenced by a foreign key constraint 'fk_users_credit_cards' on table 'credit_cards'. 一般不推荐使用这种方式,还是推荐使用Userid的方式。
三 外键关联
type User struct {gorm.ModelMemberNumber string
// 默认CreditCard会使用User表的Id作为外键,association_foreignkey:MemberNumber
// 指定使用MemberNumber 作为外键关联
CreditCards []CreditCard
`gorm:"foreignkey:UserMemberNumber;association_foreignkey:MemberNumber"`
}type CreditCard struct {gorm.ModelNumber stringUserMemberNumber string
}
其实就是creditcard外键UserMemberNumber直接去找user的 MemberNumber。
上面其实也就是改变了外键的默认值,默认外键是Userid,那么现在变为了MemberNumber。
一般使用默认id的外键就能够覆盖很多场景,上面这种只是举例。
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {gorm.ModelMemberNumber stringCreditCards []*CreditCard `gorm:"foreignKey:UserMemberNumber;association_foreignKey:MemberNumber"`
}type CreditCard struct {gorm.ModelNumber intUserMemberNumber string
}func main() {dsn6 := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn6), &gorm.Config{})db.AutoMigrate(&User{}, &CreditCard{})
}mysql> desc users;
+---------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| member_number | longtext | YES | | NULL | |
+---------------+-----------------+------+-----+---------+----------------+mysql> desc credit_cards;
+--------------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+-----------------+------+-----+---------+----------------+
| id | bigint unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime(3) | YES | | NULL | |
| updated_at | datetime(3) | YES | | NULL | |
| deleted_at | datetime(3) | YES | MUL | NULL | |
| number | bigint | YES | | NULL | |
| user_member_number | bigint unsigned | YES | MUL | NULL | |
+--------------------+-----------------+------+-----+---------+----------------+
四 创建一对多表
/*
constraint:OnUpdate:CASCADE 【当User表更新,也会同步给CreditCards】 // 外键约束
OnDelete:SET NULL 【当User中数据被删除时,CreditCard关联设置为 NULL,不删除记录】
*/type User struct {gorm.ModelUsername string `json:"username" gorm:"column:username"`CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}type CreditCard struct {gorm.ModelNumber stringUserID uint
}func main() {// 0、连接数据库dsn := "root:1@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})// 创建表结构db.AutoMigrate(User{}, CreditCard{})// 1、创建一对多user := User{Username: "zhangsan",CreditCards: []CreditCard{{Number: "0001"},{Number: "0002"},},
}db.Create(&user)// 2、为已存在用户添加信用卡u := User{Username: "zhangsan"}db.First(&u)//fmt.Println(u.Username)} 
3. 一对多Association 查找关联 使用 Association 方法, 需要把把 User 查询好, 然后根据 User 定义中指定的 AssociationForeignKey 去查找 CreditCard
import ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {gorm.ModelUserName string `json:"username" gorm:"column:username"`CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}type CreditCard struct {gorm.ModelNumber stringUserID int
}func main() {dsn6 := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn6), &gorm.Config{})db.AutoMigrate(&User{}, &CreditCard{})/*u := &User{Model: gorm.Model{},UserName: "lucas",CreditCards: []*CreditCard{{Number: "0001", UserID: 1},{Number: "0002", UserID: 2},},}db.Create(u)*/// 1、查找 用户名为 lucas 的所有信用卡信息u1 := &User{UserName: "lucas"}// Association必须要先查出User才能关联查询对应的CreditCarddb.First(u1)db.Model(u1).Association("CreditCards").Find(&u1.CreditCards)fmt.Println(u1)} 追加
package mainimport ("encoding/json""fmt""gorm.io/driver/mysql""gorm.io/gorm"
)type User struct {gorm.ModelUserName string `json:"username" gorm:"column:username"`CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
}type CreditCard struct {gorm.ModelNumber stringUserID int
}func main() {dsn6 := "root:7PXjAkY!&nlR@tcp(192.168.11.128:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"db, _ := gorm.Open(mysql.Open(dsn6), &gorm.Config{})db.AutoMigrate(&User{}, &CreditCard{})u := &User{Model: gorm.Model{},UserName: "lucas",CreditCards: []CreditCard{{Number: "0001", UserID: 0},{Number: "0002", UserID: 1},},}db.Create(u)u1 := &User{UserName: "lucas"}db.First(u1)db.Model(u1).Association("CreditCards").Find(&u1.CreditCards)fmt.Println(u1)db.Model(u1).Association("CreditCards").Append([]CreditCard{{Number: "0008", UserID: 1},})fmt.Println(u1)strUser, _ := json.Marshal(u1)fmt.Println(string(strUser))
}&{{1 2023-04-16 10:48:54.423 +0800 CST 2023-04-16 14:12:45.825 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} lucas []}&{{1 2023-04-16 10:48:54.423 +0800 CST 2023-04-16 14:15:51.44 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} lucas [{{17 2023-04-16 14:15:51.445+0800 CST 2023-04-16 14:15:51.445 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}} 0008 1}]}{"ID":1,"CreatedAt":"2023-04-16T10:48:54.423+08:00","UpdatedAt":"2023-04-16T14:15:51.44+08:00","DeletedAt":null,"username":"lucas","CreditCards":[
{"ID":17,"CreatedAt":"2023-04-16T14:15:51.445+08:00","UpdatedAt":"2023-04-16T14:15:51.445+08:00","DeletedAt":null,"Number":"0008","UserID":1}]}
4. 一对多Preload 预加载
使用 Preload 方法, 在查询 User 时先去获取 CreditCard 的记录
和上面associate不一样,他们两个最大的区别是执行的顺序是不一样的,associate是先去获取user,再去获取creditcard。
preload是先去获取creditcard,再去获取user。
package main
import (
"encoding/json"
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
/*
constraint:OnUpdate:CASCADE 【当User表更新,也会同步给CreditCards】
OnDelete:SET NULL 【当User中数据被删除时,CreditCard关联设置为 NULL,不删除记录】
*/
type User struct {
gorm.Model
Username string `json:"username" gorm:"column:username"`
CreditCards []CreditCard `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET
NULL;"`
}
type CreditCard struct {
gorm.Model
Number string
UserID uint
}
func main() {
// 0、连接数据库
dsn := "root:1@tcp(127.0.0.1:3306)/test_db?
charset=utf8mb4&parseTime=True&loc=Local"
db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// 1、预加载: 查找 user 时预加载相关 CreditCards
//users := User{Username: "zhangsan"} // 只查找张三用户的信用卡信息
users := []User{}
db.Preload("CreditCards").Find(&users)
查询结果[
{
"ID":1,
"username":"zhangsan",
"CreditCards":[
{
"ID":1,
"Number":"0001",
"UserID":1
},
...
]
}
]
相关文章:
Golang gorm
GORM 指南 | GORM - The fantastic ORM library for Golang, aims to be developer friendly. 一 对多入门 比如要开发cmdb的系统,无论是硬件还是软件。硬件对应的就是对应的哪个开发在用。或者服务对应的是哪个业务模块在使用,或者应用谁在使用。那么这…...
rk3568 适配摄像头 (CIF协议)
rk3568 适配摄像头 (CIF协议) 在RK3568处理器中,支持CIF协议的摄像头可以通过CSI接口连接到处理器,实现视频数据的采集和处理。同时,RK3568还支持多种图像处理算法和编解码器,可以对采集到的视频数据进行实时处理和压缩ÿ…...
今天面试招了个25K的测试员,从腾讯出来的果然都有两把刷子···
公司前段时间缺人,也面了不少测试,前面一开始瞄准的就是中级的水准,也没指望来大牛,提供的薪资在15-25k,面试的人很多,但平均水平很让人失望。看简历很多都是4年工作经验,但面试中,不…...
Redis---集群环境准备
一、redis集群环境准备 1、部署Redis集群的目的: 多台服务器一起提供数据存储服务; 实现数据的分布式存储; 可以实现服务的高可用; 可用实现数据自动备份; 2、服务器IP地址及端口: 主机名 IP地…...
数据结构考研版——队列的配置问题
一、正常配置下的情况 队空状态 frontrear;入队操作 出队操作 队满状态 在正常配置下元素的个数(rear>front) 当rear<front 综上所述用一个表达式表示:(rear-frontmaxSize)%maxSize 二、非正常配置下的情况1 队空状态 入队操作…...
【SOAP-WebService系列】SOAP学习笔记
目录 1、SOAP是什么? 2、SOAP特性 3、SOAP消息组成 4、SOAP调用 5、SOAP和HTTP 1、SOAP是什么? SOAP(Simple Object Access Protocol,即简单对象访问协议) ,是一个轻量级协议,用于在分散的分布式环境中使用XML在对…...
材料科学|名词解释终版!!!
晶体:组成物质的原子,分子或离子按照一定的周期性规则排列形成的固体。 非晶体:原子在三维空间的不规则排列,长程无序,各向同性。 晶体结构:原子,离子,原子团按照空间点阵而进行的…...
永久免费内网穿透不限制速度
市面上的免费内网穿透大都有格式各样的限制,什么限制流量啊,每个月要签到打卡啊,还有更改域名地址等,只有神卓互联内网穿透是永久免费没有限制的,白嫖也可以。 这篇文章分享了3个方案,按照性能和综合指标排…...
JAVA开发运维(云基础设备监控)
在大型的商用系统中,经常需要监控云设备的健康状态,性能情况,流量数据等。及时发现系统问题,及时修复,以确保系统的高可用。检查云资源的工作内容主要包括基础监控、主动拨测、用户体验、APM监控、指标体系、业务分析、…...
现在备考2023年5月软考网络工程师时间够吗?
距离2023年5月软考还有1个多月的时间,备考网络工程师的时间是够的,以下是一些备考方法: 1.了解考试内容 在你开始学习考试之前,了解考试的形式和内容是很重要的。这将帮助你把注意力集中在最有可能被测试的领域。你应该复习考试…...
webp怎么转换成png,4个方法教你快速处理
webp怎么转换成png?目前在一些比较大的图片素材网站下载的图片都是webp格式的。我们都知道webp格式图片,它在正常的图片浏览器中是无法打开的。 所以说我们要把webp图片转变成png格式,正常来说我们常用的图片处理软件也能进行格式转换&#x…...
程序员能干多久?程序员能干到多大年龄?
程序员可以工作多少年?大多数程序员认为程序员是吃青春饭的工作。编程只能干到30岁,最长可达35岁。我经常听到这样的话,都让人倍感压力。今天,我们来谈谈这个老话题...... 程序员能干多久? 根据国外的经验来说,干到…...
采购系统是如何管理供应商的?
随着数字化的推进,企业面临着越来越多的供应商管理问题。企业采购数字化转型已经成为大势所趋,对于采购数字化转型而言,供应商管理是重要一环。 供应商准入管理 在供应商准入阶段,企业需要从供应商资质、财务能力、信誉能力、管理…...
Linux学习笔记(2)--一些内核接口
1)dump_stack dump_stack()是Linux内核中的一个函数,用于在内核中输出当前的函数调用栈。该函数会输出当前线程(或进程)的函数调用栈信息,以及相应的调用地址和虚拟内存地址等信息,一般用于诊断程序运行时…...
学习风`宇博客用户权限菜单模块
文章目录 用户-角色-菜单-资源 各表关系图菜单 和 路由菜单表及分析分析 /api/admin/user/menus接口MenuServiceImpl#listUserMenus接口返回示例及分析 前端代码分析menu.jsSideBar.vue 接口权限控制资源表 及 分析分析 WebSecurityConfig权限控制整体流程先说登录UserDetailsS…...
centos7.6部署ELK集群(一)之elasticsearch7.7.0集群部署
32.3. 部署es7.7.0 32.3.1. 下载es(各节点都做) wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.7.0-linux-x86_64.tar.gz 32.3.2. 解压至安装目录(各节点都做) tar -xvf elasticsearch-7.7.0-li…...
leetcode142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数…...
Linux: network: dummy 类型网络接口
文章目录 参考创建一个重要的用途是在container平台的应用dpdk相关的一个用途另一个用途ChatGPT的回复参考 https://tldp.org/LDP/nag/node72.html 这里举了一个例子,说为什么需要dummy类型的接口:就是一个类local loopback的一个接口,当应用需要给另一个本地的应用发送包的…...
java记录-lambda表达式、接口应用、方法引用
基本形式 (str)->{System.out.println(str) };调用作为参数的接口实例的方法 1、用一个类实现接口,然后使用该类实例调用方法 2、匿名内部类 3、在 接口(不能是抽象类) 有且只有一个抽象方法时,可以使用lamda表达式来重写这个…...
AI写作机器人-ai文章生成器在线
使用AI续写生成器,让内容创作事半功倍! 随着人工智能技术的不断进步和应用,AI续写生成器的出现为内容创作带来了全新的革命。这种技术可以让你的写作事半功倍,让你轻松生成高质量的文章和内容。在这篇文章中,我们将介绍…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...
