当前位置: 首页 > news >正文

【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 的默认约定

  1. 使用结构体名的复数形式(蛇形命名)作为表名。
    • 例如:User -> 表名为 users
  2. 字段名会转换为蛇形命名作为列名。
    • 例如:CreatedAt -> 列名为 created_at
  3. 自动管理 CreatedAtUpdatedAt 字段。

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'
}

效果

  • NameEmail 字段必须有值。
  • 插入记录时,未显式设置 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.CustomerIDCustomer.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_nameauthor_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{})

数据操作

  1. 插入数据
user := User{Name: "Alice", Email: "alice@example.com"}
db.Create(&user)order := Order{UserID: user.ID, Amount: 99.99}
db.Create(&order)
  1. 查询数据
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 命令&#xff1a;start-all.sh 2.检查 hive-site.xml 和 hive-env.sh。 hive-site.xml中应设置自己mysql的用户名和密码 我的hive-site.xml如下&#xff1a; <configuration><property><name>javax.jdo.opt…...

Unity Shader学习日记 part5 CG基础

在了解完Shader的基本结构之后&#xff0c;我们再来看看编写着色器的语言。 Shader编写语言有CG&#xff0c;HLSL两种&#xff0c;我们主要学习CG的写法。 数据类型 CG的基础变量类型 uint a12;//无符号32位整形 int b12;//32位整形float f1.2f;//32位浮点型 half h1.2h;//…...

第7章:Python TDD测试Franc对象乘法功能

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

两级式三相光伏并网逆变器Matlab/Simulink仿真模型

忘记更新最经典的光伏并网仿真模型了&#xff0c;作为包含经典的MPPT和并网恒功率因素的双闭环控制模型&#xff0c;也是很多相关专业学生的入门研究内容&#xff0c;光伏并网模型三相的和单相都有。 其中三相光伏并网逆变器有大功率和小功率的两种&#xff0c;之前早在硕士期…...

redis性能优化参考——筑梦之路

基准性能测试 redis响应延迟耗时多长判定为慢&#xff1f; 比如机器硬件配置比较差&#xff0c;响应延迟10毫秒&#xff0c;就认为是慢&#xff0c;机器硬件配置比较高&#xff0c;响应延迟0.5毫秒&#xff0c;就认为是慢。这个没有固定的标准&#xff0c;只有了解了你的 Red…...

Ubuntu 22.04 TLS 忘记root密码,重启修改的解决办法

1.想办法进入这个界面&#xff0c;我这里是BIOS引导的是按Esc按一下就行&#xff0c;UEFI的貌似是按Shift不得而知&#xff0c;没操作过。下移到Advanced options for Ubuntu&#xff0c;按enter 2.根据使用的内核版本&#xff0c;选择带「recovery mode」字样的内核版本&#…...

HTML<bdo>标签

例子 指定文本方向&#xff1a; <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&#xff08;u8g2&#xff09;显示状态 实验效果3-TCP服务器OLED1 拷贝显示驱动代码1.1 拷贝源代码1.2 将源代码添加到工程1.3 修改代码优化等级1.4 添加头文件路径1.5 修改STM32CubeMX工程 2 修改源代码2.1 添加头文件2.2 main函…...

【机器学习实战中阶】使用SARIMAX,ARIMA预测比特币价格,时间序列预测

数据集说明 比特币价格预测&#xff08;轻量级CSV&#xff09;关于数据集 致谢 这些数据来自CoinMarketCap&#xff0c;并且可以免费使用该数据。 https://coinmarketcap.com/ 数据集:链接: 价格预测器 源代码与数据集 算法说明 SARIMAX&#xff08;Seasonal AutoRegressive …...

各语言镜像配置汇总

镜像配置汇总 Nodejs [ npm ]Python [ pip ] Nodejs [ npm ] // # 记录日期&#xff1a;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项目配置 &#xff08;1&#xff09;时钟 &#xff08;2&#xff09;RTC &#xff08;3&#xff09;ADC1 &#xf…...

PHP语言的循环实现

PHP语言的循环实现详解 在当今的编程世界中&#xff0c;循环是一种不可或缺的基本构造&#xff0c;它使得我们能够重复执行某些操作&#xff0c;极大地提高了代码的复用性和可读性。在PHP语言中&#xff0c;循环的种类以及使用方式繁多&#xff0c;本文将全面探讨PHP中的循环实…...

求两个矩阵的乘积

求两个矩阵的乘积 分数 15 全屏浏览 切换布局 作者 C课程组-hwr-zy 单位 浙江大学 输入三个正整数m&#xff0c;l&#xff0c;n(0<m&#xff0c;n&#xff0c;l<10)&#xff0c;再输入两个的矩阵a&#xff08;mxl&#xff09;和b&#xff08;lxn&#xff09;。要求把a和…...

警惕IDEA 2024版重大Bug问题:LomBok失效、Gradle冲突、Spring Boot启动错误

一直以来我认为工具类的软件是越新越好&#xff0c;因为工具代表着一定的先进性&#xff1b;但是IDEA 2024好好的给我上了一课&#xff0c;比如lombok 不起作用、比如Spring Boot 3.4.x 启动报错、再比如MyBatis log plus冲突、再比如Gradle插件冲突. 一、Lombok 失效问题 请不…...

Go语言的正则表达式

Go语言的正则表达式&#xff1a;深度解析与应用实例 引言 正则表达式&#xff08;Regular Expression&#xff0c;简称 regex&#xff09;是一种用于匹配字符串的强大工具&#xff0c;广泛应用于文本处理、数据验证、解析和提取等场景。Go语言作为一种现代编程语言&#xff0…...

通过ssh连接debian

使用方法 ssh usernameipaddress [inputpasswd]root用户默认无法由ssh连接&#xff0c; 可以通过修改配置 sudo vim /etc/ssh/sshd_config去掉PermitRootLogin前的‘#’,并修改为 PermitRootLogin yes 重启sshd服务 sudo systemctl restart sshd参考 https://linuxconfig.or…...

计算机创造的奇迹——C语言

一.简介 C语言是一种较早的程序设计语言&#xff0c;诞生于1972年的贝尔实验室。1972 年&#xff0c;Dennis Ritchie 设计了C语言&#xff0c;它继承了B语言的许多思想&#xff0c;并加入了数据类型的概念及其他特性。 尽管C 语言是与 UNIX 操作系统一起被开发出来的&#xff…...

算术运算符(i++与++i)

i与i在独立使用时结果一致&#xff1b;作为表达式使用时&#xff1a;j 8&#xff08;1&#xff09;k j 等于 j j1&#xff0c;再k j 。先自增&#xff0c;再赋值 &#xff0c;j9&#xff0c;k9&#xff08;2&#xff09; k j 等于 k j&#xff0c;再j j1 。先赋值&#…...

多人对话场景模拟:交替使用不同音色生成对话片段

多人对话场景模拟&#xff1a;交替使用不同音色生成对话片段 1. 引言&#xff1a;让AI语音对话更真实自然 想象一下这样的场景&#xff1a;你需要制作一段多人对话的音频内容&#xff0c;可能是教学演示、广播剧、或者产品介绍。传统方法需要找不同的人录音&#xff0c;费时费…...

Lingyuxiu MXJ LoRA深度学习优化:训练加速技巧

Lingyuxiu MXJ LoRA深度学习优化&#xff1a;训练加速技巧 深度学习训练往往需要大量时间和计算资源&#xff0c;但通过一些巧妙的优化技巧&#xff0c;我们可以显著提升训练效率。本文将分享针对Lingyuxiu MXJ LoRA模型的训练加速方法&#xff0c;让你用更少的时间获得更好的效…...

OpenClaw日程管理:千问3.5-9B解析邮件创建待办

OpenClaw日程管理&#xff1a;千问3.5-9B解析邮件创建待办 1. 为什么需要AI助手管理日程&#xff1f; 每天早上打开邮箱&#xff0c;总能看到十几封未读邮件——会议邀请、项目更新、待办提醒混杂在一起。上周我就因为漏看了一封包含截止日期变更的邮件&#xff0c;差点耽误了…...

深入FreeRTOS SMP调度器:主核与从核如何“默契配合”完成第一次任务切换?

深入FreeRTOS SMP调度器&#xff1a;主核与从核如何“默契配合”完成第一次任务切换&#xff1f; 在嵌入式系统开发中&#xff0c;实时操作系统&#xff08;RTOS&#xff09;的多核支持已成为提升性能的关键。FreeRTOS作为业界广泛采用的RTOS&#xff0c;其SMP&#xff08;对称…...

通义千问1.5-1.8B-Chat-GPTQ-Int4一键部署效果展示:低显存占用下的流畅对话体验

通义千问1.5-1.8B-Chat-GPTQ-Int4一键部署效果展示&#xff1a;低显存占用下的流畅对话体验 最近在尝试各种轻量级大模型本地部署&#xff0c;一个绕不开的痛点就是显存。动不动就十几GB的显存需求&#xff0c;让很多只有一张普通消费级显卡的朋友望而却步。正好&#xff0c;我…...

OpenClaw+Qwen3-14b_int4_awq低成本方案:自建模型接口替代OpenAI API

OpenClawQwen3-14b_int4_awq低成本方案&#xff1a;自建模型接口替代OpenAI API 1. 为什么需要本地模型替代OpenAI API 去年我在开发一个自动化内容处理系统时&#xff0c;遇到了一个棘手的问题&#xff1a;OpenAI API的Token消耗速度远超预期。当时系统需要处理大量长文本&a…...

Matlab七次非均匀B样条轨迹规划及基于NSGAII的优化方法

matlab-B样条轨迹规划-1 七次非均匀B样条轨迹规划&#xff0c; 基于NSGAII的时间-能量-冲击最优。 换上自己的关节值和时间就能用&#xff0c;简单好用&#xff0c;最近在搞机器人轨迹规划&#xff0c;发现七次非均匀B样条真是个好东西。它不仅能保证轨迹的平滑性&#xff0c;还…...

色彩心理学与品牌情感:vibrant.js颜色提取终极指南 [特殊字符]

色彩心理学与品牌情感&#xff1a;vibrant.js颜色提取终极指南 &#x1f3a8; 【免费下载链接】vibrant.js Extract prominent colors from an image. JS port of Androids Palette. 项目地址: https://gitcode.com/gh_mirrors/vi/vibrant.js 在数字时代&#xff0c;色彩…...

CherryStudio+Obsidian组合拳:打造自动更新的个人AI知识中枢

CherryStudioObsidian组合拳&#xff1a;打造自动更新的个人AI知识中枢 在信息爆炸的时代&#xff0c;科研人员和专业写作者面临的最大挑战不是获取知识&#xff0c;而是如何高效管理和持续更新个人知识体系。传统笔记工具虽然能帮助我们收集信息&#xff0c;但当知识量达到数千…...