【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 操作系统一起被开发出来的ÿ…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...