【GORM】初探gorm模型,字段标签与go案例
GORM是什么?
- GORM 是一个Go 语言 ORM(对象关系映射)库,它让我们可以使用结构体来操作数据库,而无需编写SQL 语句
GORM 模型与字段标签详解
在 GORM 中,模型是数据库表的抽象表示,字段标签(Tag)则用于指定模型字段与数据库字段之间的映射规则及行为。
1. 模型定义
模型是由 Go 的结构体定义的,它表示数据库中的一张表。GORM 默认遵循约定优于配置的原则,提供了很多自动化功能。
基本模型示例
type User struct {ID uint `gorm:"primaryKey"` // 主键Name string `gorm:"size:100"` // 字符串最大长度为 100Email string `gorm:"unique"` // 唯一字段Age uint8 `gorm:"check:age >= 0"` // 年龄必须非负CreatedAt time.Time // 创建时间UpdatedAt time.Time // 更新时间
}
GORM 的默认约定
- 使用结构体名的复数形式(蛇形命名)作为表名。
- 例如:
User-> 表名为users。
- 例如:
- 字段名会转换为蛇形命名作为列名。
- 例如:
CreatedAt-> 列名为created_at。
- 例如:
- 自动管理
CreatedAt和UpdatedAt字段。
2. 字段标签详解
GORM 提供了丰富的字段标签,帮助我们定制模型字段的行为。以下是常用标签的分类及示例。
2.1 主键和自增
primaryKey:设置主键。autoIncrement:设置字段为自增。
type Product struct {ID uint `gorm:"primaryKey;autoIncrement"`Name stringPrice float64
}
效果:ID 字段为自增主键。
2.2 字段属性
size:设置字符串类型字段的最大长度。not null:设置字段不能为空。default:设置字段的默认值。unique:设置字段为唯一约束。
type Customer struct {ID uintName string `gorm:"size:50;not null"` // 最长 50 字符,不能为空Email string `gorm:"unique;not null"` // 唯一且不能为空Status string `gorm:"default:'active'"` // 默认值为 'active'
}
效果:
Name和Email字段必须有值。- 插入记录时,未显式设置
Status的值时,将使用默认值。
2.3 外键与关联
foreignKey:定义外键字段。references:指定外键引用的字段。constraint:设置外键的约束行为。
type Order struct {ID uintCustomerID uint `gorm:"not null"`Customer Customer `gorm:"foreignKey:CustomerID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}
效果:
Order.CustomerID是Customer.ID的外键。- 更新
Customer.ID时级联更新,删除Customer时将CustomerID设为 NULL。
2.4 时间字段
autoCreateTime:自动设置为记录创建时间。autoUpdateTime:自动设置为记录更新时间。
type Post struct {ID uintTitle stringCreatedAt int64 `gorm:"autoCreateTime"` // 使用 Unix 时间戳UpdatedAt int64 `gorm:"autoUpdateTime:nano"` // 使用纳秒时间戳
}
2.5 嵌套结构体
GORM 支持将结构体嵌套到模型中,通过标签自定义嵌套字段的列名前缀。
type Author struct {Name stringEmail string
}type Blog struct {ID uintAuthor Author `gorm:"embedded;embeddedPrefix:author_"`Content string
}
效果:
Author的字段会被展开,数据库表的列名为author_name和author_email。
3. 实际案例:用户与订单系统
以下是一个用户和订单的实际案例,展示如何使用模型和字段标签。
模型定义
type User struct {ID uint `gorm:"primaryKey"`Name string `gorm:"size:100;not null"`Email string `gorm:"uniqueIndex;not null"`Orders []Order `gorm:"foreignKey:UserID"`CreatedAt time.TimeUpdatedAt time.Time
}type Order struct {ID uint `gorm:"primaryKey"`UserID uint `gorm:"not null"`Amount float64 `gorm:"not null"`Status string `gorm:"default:'pending'"`CreatedAt time.Time
}
数据库迁移
使用 AutoMigrate 自动生成表结构:
db.AutoMigrate(&User{}, &Order{})
数据操作
- 插入数据
user := User{Name: "Alice", Email: "alice@example.com"}
db.Create(&user)order := Order{UserID: user.ID, Amount: 99.99}
db.Create(&order)
- 查询数据
var user User
db.Preload("Orders").First(&user)
fmt.Printf("用户信息: %+v\\n", user)
4. 总结
| 标签 | 描述 | 示例 |
|---|
| primaryKey | 设置字段为主键 | gorm:\"primaryKey\" |
| size | 设置字符串字段长度 | gorm:\"size:255\" |
| not null | 设置字段不能为空 | gorm:\"not null\" |
| unique | 设置字段唯一性约束 | gorm:\"unique\" |
| autoCreateTime| 自动记录创建时间 | gorm:\"autoCreateTime\" |
| foreignKey | 定义外键字段 | gorm:\"foreignKey:UserID\"|
| embedded | 嵌套结构体字段 | gorm:\"embedded\" |
go案例展示
conn.go
package _caseimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""log""os""time"
)var DB *gorm.DB/*
用户名和密码:root:123456
root 是数据库用户名。
123456 是数据库密码。
网络协议和地址:@tcp(192.168.88.131:3306)
@tcp 表示使用 TCP 协议进行连接。
192.168.88.131 是数据库服务器的 IP 地址。
3306 是 MySQL 默认端口号。
数据库名称:/mydb
mydb 是要连接的数据库名称。
查询参数:
charset=utf8mb4:指定字符集为 utf8mb4,支持完整的 Unicode 编码,包括表情符号等。
parseTime=True:将时间字段解析为 Go 的 time.Time 类型。
loc=Local:设置时区为本地时区。// 保存与数据库的连接实例
*/
var dsn = "root:123456@tcp(192.168.88.131:3306)/mydb?charset=utf8mb4&parseTime=True&loc=Local" // 数据源名称(DSN)// 为了提高安全性,避免硬编码敏感信息(如用户名和密码),可以使用环境变量来存储这些信息。
func getDSN() string {return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",os.Getenv("DB_USER"),os.Getenv("DB_PASSWORD"),os.Getenv("DB_HOST"),os.Getenv("DB_PORT"),os.Getenv("DB_NAME"))
}// 使用 GORM 库连接 MySQL 数据库,并配置数据库连接池。
func init() {var err errorDB, err = gorm.Open(mysql.New(mysql.Config{ // gorm.Open 打开数据库连接 ,第一个参数mysql.Config是mysql配置对象DSN: dsn,DefaultStringSize: 256,}), &gorm.Config{ // 第二个参数gorm.Config gorm配置Logger: logger.Default.LogMode(logger.Info), // 设置日志级别为Info// 开启预编译,提高后续调用速度// 开启预编译情况,不支持嵌套事务// PrepareStmt: true})if err != nil {log.Println(err)return}setPool(DB)
}// 设置数据库连接池
func setPool(db *gorm.DB) {sqlDB, err := db.DB() // 获取底层的*sql.DBif err != nil {log.Println(err)return}sqlDB.SetMaxOpenConns(100) // 设置最大打开连接数sqlDB.SetMaxIdleConns(10) // 设置最大空闲连接数sqlDB.SetConnMaxLifetime(time.Hour) // 设置连接最大生命周期
}
models.go
package _caseimport "gorm.io/gorm"// init函数在程序启动时初始化数据库迁移
// 使用了AutoMigrate方法来自动迁移Teacher和Course模型
// 确保了表结构与 Go 结构体定义保持同步
func init() {DB.Migrator().AutoMigrate(Teacher{}, Course{}) // migrator 迁移器 autoMigrate 自动迁移
}type Roles []string // 存储教师的角色信息
// Teacher 结构体代表了一个教师实体,用于在数据库中存储教师的相关信息。
// 通过 GORM 标签,定义了各个字段在数据库中的行为和约束。
type Teacher struct {gorm.Model // 继承自 GORM 的默认模型,包含 ID, CreatedAt, UpdatedAt, DeletedAt 字段Name string `gorm:"size:256"` // 教师的姓名,最多256个字符Email string `gorm:"size:256"` // 教师的电子邮件地址,最多256个字符Salary float64 `gorm:"scale:2;precision:7"` // 教师的工资,使用7位精度和2位小数表示Age uint8 `gorm:"check:age>30"` // 教师的年龄,数据库中有一个检查约束确保年龄大于30Birthday int64 `gorm:"serializer:unixtime;type:time"` // 教师的生日,以Unix时间戳的形式存储Roles Roles `gorm:"serializer:json"` // 教师的角色,以JSON格式序列化存储JobInfo Job `gorm:"embedded;embeddedPrefix:job_"` // 嵌入的Job结构体,表示教师的职业信息,字段名前缀为job_JobInfo2 Job `gorm:"type:bytes;serializer:gob"` // 另一种形式的教师职业信息存储,使用GOB序列化方式存储为字节类型
}type Job struct {Title stringLocation string
}// Course 结构体代表了一个课程实体,包括课程的基本信息及其与用户的关系。
// 该结构体使用了gorm.Model,这意味着它包含了通用的字段如ID、创建时间、更新时间和删除时间,用于ORM操作。
type Course struct {// gorm.Model 嵌入式通用模型,提供基础的ORM功能。gorm.Model// Name 字段表示课程的名称,使用gorm注释指定最大长度为256字符。Name string `gorm:"size:256"`// Price 字段表示课程的价格,其中scale:2表示小数点后保留两位,precision:7表示总共可以存储7位数字(包括小数点后的数字)。Price float64 `gorm:"scale:2;precision:7"`// UserID 字段表示创建或关联该课程的用户ID,使用gorm注释指定其数据库中的类型为int。UserID uint `gorm:"type:int"`
}
main.go
package mainimport (_ "golang15-gorm/case"
)func main() {}

https://github.com/0voice
相关文章:
【GORM】初探gorm模型,字段标签与go案例
GORM是什么? GORM 是一个Go 语言 ORM(对象关系映射)库,它让我们可以使用结构体来操作数据库,而无需编写SQL 语句 GORM 模型与字段标签详解 在 GORM 中,模型是数据库表的抽象表示,字段标签&am…...
Windows下的Milvus安装秘籍:向量数据库轻松上手
目录 一、简介 二、dockers的安装 1.介绍 2.环境准备 1.启动WSL 的功能。 2.安装并启动Hyper-V Windows10下的安装办法: Windows11下的安装办法: 启动Hyper-V 3.Docker的安装 4、验证是否安装成功 三、安装Milvus 1.Milvus下载 2.Milvus启动…...
在GUI中添加一个Label
标签是一种非常简单的小部件,它可以为我们的图形用户界面(GUI)增添价值。它可以阐释其他组件的用途,提供一些额外的信息,这可以引导用户理解输入框组件的含义,也能够解释那些无需用户输入数据的组件所显示数据的含义。 准备就绪 我们将扩展第一个应用案例,即《创建第一…...
hive连接mysql报错:Unknown version specified for initialization: 3.1.0
分享下一些报错的可能原因吧 1.要开启hadoop 命令:start-all.sh 2.检查 hive-site.xml 和 hive-env.sh。 hive-site.xml中应设置自己mysql的用户名和密码 我的hive-site.xml如下: <configuration><property><name>javax.jdo.opt…...
Unity Shader学习日记 part5 CG基础
在了解完Shader的基本结构之后,我们再来看看编写着色器的语言。 Shader编写语言有CG,HLSL两种,我们主要学习CG的写法。 数据类型 CG的基础变量类型 uint a12;//无符号32位整形 int b12;//32位整形float f1.2f;//32位浮点型 half h1.2h;//…...
第7章:Python TDD测试Franc对象乘法功能
写在前面 这本书是我们老板推荐过的,我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后,我突然思考,对于测试开发工程师来说,什么才更有价值呢?如何让 AI 工具更好地辅助自己写代码,或许…...
两级式三相光伏并网逆变器Matlab/Simulink仿真模型
忘记更新最经典的光伏并网仿真模型了,作为包含经典的MPPT和并网恒功率因素的双闭环控制模型,也是很多相关专业学生的入门研究内容,光伏并网模型三相的和单相都有。 其中三相光伏并网逆变器有大功率和小功率的两种,之前早在硕士期…...
redis性能优化参考——筑梦之路
基准性能测试 redis响应延迟耗时多长判定为慢? 比如机器硬件配置比较差,响应延迟10毫秒,就认为是慢,机器硬件配置比较高,响应延迟0.5毫秒,就认为是慢。这个没有固定的标准,只有了解了你的 Red…...
Ubuntu 22.04 TLS 忘记root密码,重启修改的解决办法
1.想办法进入这个界面,我这里是BIOS引导的是按Esc按一下就行,UEFI的貌似是按Shift不得而知,没操作过。下移到Advanced options for Ubuntu,按enter 2.根据使用的内核版本,选择带「recovery mode」字样的内核版本&#…...
HTML<bdo>标签
例子 指定文本方向: <bdo dir"rtl"> This text will go right-to-left. </bdo> <!DOCTYPE html> <html> <body> <h1>The bdo element</h1> <p>This paragraph will go left-to-right.</p> …...
STM32+W5500+以太网应用开发+003_TCP服务器添加OLED(u8g2)显示状态
STM32W5500以太网应用开发003_TCP服务器添加OLED(u8g2)显示状态 实验效果3-TCP服务器OLED1 拷贝显示驱动代码1.1 拷贝源代码1.2 将源代码添加到工程1.3 修改代码优化等级1.4 添加头文件路径1.5 修改STM32CubeMX工程 2 修改源代码2.1 添加头文件2.2 main函…...
【机器学习实战中阶】使用SARIMAX,ARIMA预测比特币价格,时间序列预测
数据集说明 比特币价格预测(轻量级CSV)关于数据集 致谢 这些数据来自CoinMarketCap,并且可以免费使用该数据。 https://coinmarketcap.com/ 数据集:链接: 价格预测器 源代码与数据集 算法说明 SARIMAX(Seasonal AutoRegressive …...
各语言镜像配置汇总
镜像配置汇总 Nodejs [ npm ]Python [ pip ] Nodejs [ npm ] // # 记录日期:2025-01-20// 查询当前使用的镜像 npm get registry// 设置淘宝镜像 npm config set registry https://registry.npmmirror.com/// 恢复为官方镜像 npm config set registry https://regi…...
细说STM32F407单片机电源低功耗StopMode模式及应用示例
目录 一、停止模式基础知识 1、进入停止模式 2、停止模式的状态 3、退出停止模式 4、SysTick定时器的影响 二、停止模式应用示例 1、示例功能和CubeMX项目配置 (1)时钟 (2)RTC (3)ADC1 …...
PHP语言的循环实现
PHP语言的循环实现详解 在当今的编程世界中,循环是一种不可或缺的基本构造,它使得我们能够重复执行某些操作,极大地提高了代码的复用性和可读性。在PHP语言中,循环的种类以及使用方式繁多,本文将全面探讨PHP中的循环实…...
求两个矩阵的乘积
求两个矩阵的乘积 分数 15 全屏浏览 切换布局 作者 C课程组-hwr-zy 单位 浙江大学 输入三个正整数m,l,n(0<m,n,l<10),再输入两个的矩阵a(mxl)和b(lxn)。要求把a和…...
警惕IDEA 2024版重大Bug问题:LomBok失效、Gradle冲突、Spring Boot启动错误
一直以来我认为工具类的软件是越新越好,因为工具代表着一定的先进性;但是IDEA 2024好好的给我上了一课,比如lombok 不起作用、比如Spring Boot 3.4.x 启动报错、再比如MyBatis log plus冲突、再比如Gradle插件冲突. 一、Lombok 失效问题 请不…...
Go语言的正则表达式
Go语言的正则表达式:深度解析与应用实例 引言 正则表达式(Regular Expression,简称 regex)是一种用于匹配字符串的强大工具,广泛应用于文本处理、数据验证、解析和提取等场景。Go语言作为一种现代编程语言࿰…...
通过ssh连接debian
使用方法 ssh usernameipaddress [inputpasswd]root用户默认无法由ssh连接, 可以通过修改配置 sudo vim /etc/ssh/sshd_config去掉PermitRootLogin前的‘#’,并修改为 PermitRootLogin yes 重启sshd服务 sudo systemctl restart sshd参考 https://linuxconfig.or…...
计算机创造的奇迹——C语言
一.简介 C语言是一种较早的程序设计语言,诞生于1972年的贝尔实验室。1972 年,Dennis Ritchie 设计了C语言,它继承了B语言的许多思想,并加入了数据类型的概念及其他特性。 尽管C 语言是与 UNIX 操作系统一起被开发出来的ÿ…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
