3.2goweb框架GORM

GORM 是 Go 语言中功能强大的 ORM(对象关系映射)框架,支持 MySQL、PostgreSQL、SQLite、SQL Server 等主流数据库。以下是 GORM 的核心概念和用法详解:


​一、基础入门​

1. 安装
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql  # 按需选择数据库驱动

所以我们看到安装的最新版本是 1.26.0.这个不是Gorm1.0的意思。是GORM2.0.参考官方2.0的文档。https://gorm.io/zh_CN/docs/

2. 连接数据库
import ("gorm.io/driver/mysql""gorm.io/gorm"
)dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

Gorm 有一个 默认 logger 实现,默认情况下,它会打印慢 SQL 和错误

Logger 接受的选项不多,您可以在初始化时自定义它,例如:

newLogger := logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), // io writerlogger.Config{SlowThreshold:              time.Second,   // Slow SQL thresholdLogLevel:                   logger.Silent, // Log levelIgnoreRecordNotFoundError: true,           // Ignore ErrRecordNotFound error for loggerParameterizedQueries:      true,           // Don't include params in the SQL logColorful:                  false,          // Disable color},
)// Globally mode
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{Logger: newLogger,
})// Continuous session mode
tx := db.Session(&Session{Logger: newLogger})
tx.First(&user)
tx.Model(&user).Update("Age", 18)
日志级别

GORM 定义了这些日志级别:SilentErrorWarnInfo


​二、模型定义​

1. 结构体与表映射
type User struct {gorm.Model        // 内置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}
2. 自定义表名
func (User) TableName() string {return "custom_users" // 自定义表名
}
3.自动迁移

GORM 提供的自动迁移功能是指它能够根据定义的 Go 结构体(模型)自动创建、更新或删除数据库中的表结构,以此保持模型和数据库表结构的一致性。这一功能极大地简化了数据库表结构管理的流程。例如,当你新增一个字段到结构体中,自动迁移会尝试在数据库表中添加该字段;若删除了结构体中的某个字段,自动迁移也可能根据配置删除表中的相应列。

工作原理
  1. 解析模型定义:GORM 会解析你定义的 Go 结构体,识别其中的字段、类型、标签等信息。例如,对于以下 User 结构

type User struct {gorm.Model        // 内置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}func (User) TableName() string {return "custom_users" // 自定义表名
}

GORM 会分析出 User 表应该包含 idcreated_atupdated_atdeleted_at(来自 gorm.Model)、nameemail 和 age 这些字段,并且 email 字段需要有唯一约束。
2. 生成 SQL 语句:根据解析结果,GORM 生成相应的 SQL 语句。如果数据库中不存在 custom_users表,会生成 CREATE TABLE 语句来创建表;若表已存在,会生成 ALTER TABLE 语句来更新表结构。
3. 执行 SQL 语句:GORM 将生成的 SQL 语句发送到数据库执行,从而完成表结构的创建或更新。

使用示例
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)// User 模型定义
type User struct {gorm.Model        // 内置字段:ID, CreatedAt, UpdatedAt, DeletedAtName       string `gorm:"size:255"`Age        intEmail      string `gorm:"uniqueIndex size:255"` // 唯一索引
}func (User) TableName() string {return "custom_users" // 自定义表名
}func main() {dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic("failed to connect database")}// 自动迁移 User 模型db.AutoMigrate(&User{})
}

输出结果:

在上述代码中,调用 db.AutoMigrate(&User{}) 会根据 User 结构体的定义在数据库中创建或更新 User 表。

注意事项
  • 数据丢失风险:自动迁移可能会导致数据丢失。例如,当你删除结构体中的某个字段时,自动迁移可能会删除数据库表中的相应列,该列的数据就会丢失。所以在生产环境中最好不要使用该功能。

​三、CRUD 操作​

1. 创建记录
// 创建单条
user := User{Name: "Alice", Age: 25}
db.Create(&user)// 批量插入
users := []User{{Name: "Bob"}, {Name: "Charlie"}}
db.CreateInBatches(users, 100) // 每批100条
2. 查询数据
var users []User// 查询全部
db.Find(&users)// 条件查询
db.Where("age > ?", 18).Find(&users)
db.First(&user, 1)        // 查找ID=1的第一条记录
db.Last(&user)            // 最后一条记录// 高级查询
db.Select("name, age").Where("age > ?", 20).Order("age desc").Limit(10).Find(&users)
3. 更新数据
// 更新单个字段
db.Model(&user).Update("Age", 30)// 批量更新
db.Model(&User{}).Where("age < ?", 30).Update("Age", gorm.Expr("Age + ?", 1))
4. 删除数据
// 软删除(默认使用 DeletedAt 字段)
db.Delete(&user)// 硬删除(物理删除)
db.Unscoped().Delete(&user)

​四、关联关系​

一对一关联

package mainimport "gorm.io/gorm"// User 用户模型
type User struct {gorm.ModelName    stringProfile Profile
}// Profile 个人资料模型
type Profile struct {gorm.ModelUserID  uintAddress string
}

在这个例子中,User 结构体包含一个 Profile 字段,Profile 结构体包含一个 UserID 字段作为外键,关联到 User 表。

迁移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自动迁移模型db.AutoMigrate(&User{}, &Profile{})// 创建用户和关联的个人资料user := User{Name: "John Doe",Profile: Profile{Address: "123 Main St",},}db.Create(&user)// 查询用户及其个人资料var retrievedUser Userdb.Preload("Profile").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Address: %s\n", retrievedUser.Name, retrievedUser.Profile.Address)
}

在这个例子中,我们使用 Preload 方法预加载用户的个人资料。

一对多关联

一对多关联表示一个模型的一条记录可以关联到另一个模型的多条记录。例如,一个用户可以有多个帖子。

package mainimport "gorm.io/gorm"// User 用户模型
type User struct {gorm.ModelName  stringPosts []Post
}// Post 帖子模型
type Post struct {gorm.ModelTitle  stringUserID uint
}

在这个例子中,User 结构体包含一个 Posts 切片,Post 结构体包含一个 UserID 字段作为外键,关联到 User 表。

迁移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自动迁移模型db.AutoMigrate(&User{}, &Post{})// 创建用户和关联的帖子user := User{Name: "John Doe",Posts: []Post{{Title: "First Post"},{Title: "Second Post"},},}db.Create(&user)// 查询用户及其帖子var retrievedUser Userdb.Preload("Posts").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Posts count: %d\n", retrievedUser.Name, len(retrievedUser.Posts))
}

在这个例子中,我们同样使用 Preload 方法预加载用户的所有帖子。

多对多关联

多对多关联表示一个模型的一条记录可以关联到另一个模型的多条记录,反之亦然。例如,一个用户可以有多个角色,一个角色可以被多个用户拥有。

定义模型
package mainimport "gorm.io/gorm"// User 用户模型
type User struct {gorm.ModelName  stringRoles []Role `gorm:"many2many:user_roles;"`
}// Role 角色模型
type Role struct {gorm.ModelName  stringUsers []User `gorm:"many2many:user_roles;"`
}

在这个例子中,User 结构体和 Role 结构体都包含一个切片,通过 many2many 标签指定关联表为 user_roles

迁移和操作示例
package mainimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm"
)func ConnectDB() (*gorm.DB, error) {dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {return nil, err}return db, nil
}func main() {db, err := ConnectDB()if err != nil {panic("failed to connect database")}// 自动迁移模型db.AutoMigrate(&User{}, &Role{})// 创建用户和角色user := User{Name: "John Doe"}role := Role{Name: "Admin"}db.Create(&user)db.Create(&role)// 关联用户和角色db.Model(&user).Association("Roles").Append(&role)// 查询用户及其角色var retrievedUser Userdb.Preload("Roles").First(&retrievedUser, user.ID)fmt.Printf("User: %s, Roles count: %d\n", retrievedUser.Name, len(retrievedUser.Roles))
}

我们使用 Association 方法将用户和角色关联起来,然后使用 Preload 方法预加载用户的所有角色。

  • 预加载:使用 Preload 方法可以在查询主模型时同时加载关联的模型数据,避免 N+1 查询问题。
  • 关联操作:对于多对多关联,可以使用 Association 方法进行关联的添加、删除等操作。
  • 迁移:在使用关联关系之前,需要确保模型已经通过 AutoMigrate 方法进行了迁移,以创建相应的表和外键约束。

  • ​循环引用​​:确保模型间没有相互嵌套导致无限递归。
  • ​性能优化​​:避免 SELECT *,明确指定需要的字段。
  • ​索引优化​​:在频繁查询的字段上添加索引(如 gorm:"index")。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/78964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三部分:特征提取与目标检测

像边缘、角点、特定的纹理模式等都是图像的特征。提取这些特征是许多计算机视觉任务的关键第一步&#xff0c;例如图像匹配、对象识别、图像拼接等。目标检测则是在图像中找到特定对象&#xff08;如人脸、汽车等&#xff09;的位置。 本部分将涵盖以下关键主题&#xff1a; …

Canvas基础篇:图形绘制

Canvas基础篇&#xff1a;图形绘制 图形绘制moveTo()lineTo()lineTo绘制一条直线代码示例效果预览 lineTo绘制平行线代码示例效果预览 lineTo绘制矩形代码示例效果预览 arc()arc绘制一个圆代码实现效果预览 arc绘制一段弧代码实现效果预览 arcTo()rect()曲线 结语 图形绘制 在…

瑞芯微芯片算法开发初步实践

文章目录 一、算法开发的一般步骤1.选择合适的深度学习框架2.对于要处理的问题进行分类&#xff0c;是回归问题还是分类问题。3.对数据进行归纳和整理4.对输入的数据进行归一化和量化&#xff0c;保证模型运行的效率和提高模型运行的准确度5.在嵌入式处理器上面运行模型&#x…

计算机毕业设计--基于深度学习(U-Net与多尺度ViT)的模糊车牌图像清晰化复原算法设计与实现(含Github代码+Web端在线体验链接)

基于深度学习的U-Net架构下多尺度Transformer车牌图像去模糊算法设计与实现 如果想对旧照片进行模糊去除&#xff0c;划痕修复、清晰化&#xff0c;请参考这篇CSDN作品&#x1f447; 计算机毕业设计–基于深度学习的图像修复&#xff08;清晰化划痕修复色彩增强&#xff09;算…

(Go Gin)Gin学习笔记(四)Gin的数据渲染和中间件的使用:数据渲染、返回JSON、浅.JSON()源码、中间件、Next()方法

1. 数据渲染 1.1 各种数据格式的响应 json、结构体、XML、YAML类似于java的properties、ProtoBuf 1.1.1 返回JSON package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {r : gin.Default()r.POST("/demo", func(res *gi…

实验:串口通信

/************************************************* * AT89C52 串口通信实验&#xff08;实用修正版&#xff09; * 特点&#xff1a; * 1. 解决所有编译警告 * 2. 保持代码简洁 * 3. 完全功能正常 ************************************************/ #include <re…

智驾赛道的诺曼底登陆,Momenta上海车展雄起

作者 |芦苇 编辑 |德新 今年的上海车展依旧热闹非凡&#xff0c;但火热的车市背后也是暗流涌动。尤其对智驾供应商而言&#xff0c;「智驾平权」带动了解决方案大量上车&#xff0c;各大主机厂纷纷选定各自的主要供应商&#xff0c;这也意味着赛道机会越发收敛。 正如汽车品牌…

Java 事务详解

目录 一、事务的基本概念1.1 什么是事务?1.2 事务的 ACID 特性二、Java 事务管理的实现方式2.1 JDBC 事务管理2.2 Spring 事务管理2.2.1 添加 Spring 依赖2.2.2 配置 Spring 事务管理2.2.3 使用 Spring 事务注解三、事务隔离级别四、最佳实践4.1 尽量缩小事务范围4.2 合理选择…

DirectX12(D3D12)基础教程七 深度模板视图\剔除\谓词

本章主要讲遮挡&#xff0c;作者认为比较复杂有难度的知识点&#xff0c;作为基础教程不会深入讲解。 GPU渲染管线 主要包括以下阶段 输入装配&#xff08;IA&#xff09;&#xff1a;读取顶点数据 &#xff0c;定义顶点数据结构顶点着色&#xff08;VS&#xff09;&#xf…

温补晶振(TCXO)稳定性优化:从实验室到量产的关键技术

在现代通信、航空航天、5G基站等对频率稳定性要求极高的领域&#xff0c;温补晶振&#xff08;TCXO&#xff09;扮演着不可或缺的角色。其稳定性直接影响系统的性能与可靠性&#xff0c;因此&#xff0c;对TCXO稳定性优化技术的研究与实践至关重要。 一、温度补偿算法&#xff…

C++,设计模式,【建造者模式】

文章目录 通俗易懂的建造者模式&#xff1a;手把手教你造电脑一、现实中的建造者困境二、建造者模式核心思想三、代码实战&#xff1a;组装电脑1. 产品类 - 电脑2. 抽象建造者 - 装机师傅3. 具体建造者 - 电竞主机版4. 具体建造者 - 办公主机版5. 指挥官 - 装机总控6. 客户端使…

前端基础之《Vue(13)—重要API》

重要的API 一、nextTick() 1、写法 Vue.$nextTick()或者this.$nextTick() 原因&#xff1a; set操作代码是同步的&#xff0c;但是代码背后的行为是异步的。set操作修改声明式变量&#xff0c;触发re-render生成新的虚拟DOM&#xff0c;进一步执行diff运算&#xff0c;找到…

Windows 中搭建 browser-use WebUI 1.4

目录 1. 背景介绍2. 搭建过程3. 补充 1. 背景介绍 背景&#xff1a;想要在 Windows 中复现 browser-use WebUI pickle反序列化漏洞&#xff0c;该漏洞在 v1.7 版本中已经修复&#xff0c;所以需要搭建 小于 1.7 版本的环境&#xff0c;我这里搭建的是 1.4 版本。 项目地址&am…

【数据通信完全指南】从物理层到协议栈的深度解析

目录 1. 通信技术演进与核心挑战1.1 从电报到5G的技术变迁1.2 现代通信系统的三大瓶颈 2. 通信系统架构深度解构2.1 OSI七层模型运作原理2.2 TCP/IP协议栈实战解析 3. 物理层关键技术实现3.1 信号调制技术演进路线3.2 信道复用方案对比 4. 数据传输可靠性保障4.1 CRC校验算法数…

CMD与PowerShell:Windows命令行工具的对比与使用指南

CMD与PowerShell&#xff1a;Windows命令行工具的对比与使用指南 文章目录 CMD与PowerShell&#xff1a;Windows命令行工具的对比与使用指南引言1. CMD&#xff08;命令提示符&#xff09;简介1.1 什么是CMD&#xff1f;1.2 CMD的特点1.3 常用CMD命令示例1.4 CMD的优势与局限 2…

93. 后台线程与主线程更新UI Maui例子 C#例子

在.NET MAUI开发中&#xff0c;多线程是常见的需求&#xff0c;但UI更新必须在主线程上执行。今天&#xff0c;我们来探讨一个简单而优雅的解决方案&#xff1a;MainThread.InvokeOnMainThreadAsync。 一、背景 在跨平台应用开发中&#xff0c;后台线程常用于执行耗时操作&am…

海思正式公开了星闪BS21E的SDK

今天海思正式在Gitee平台发布了BS21E的SDK&#xff1a;fbb_bs2x: fbb_bs2x代码仓为支持bs21e解决方案SDK。技术论坛&#xff1a;https://developers.hisilicon.com/forum/0133146886267870001 fbb_bs2x代码仓为支持bs21e解决方案SDK&#xff0c;该SDK包从统一开发平台FBB&#…

QML学习:使用QML实现抽屉式侧边栏菜单

文章目录 前言一、环境配置二、实现步骤三、示例完整代码四、注意事项总结 前言 最近在进行QML的学习&#xff0c;发现一个比较有意思的交互设计&#xff1a;抽屉式侧边栏菜单&#xff0c;出于开发实战需求&#xff0c;最终实现了一个支持手势拖拽、弹性动画、蒙层效果和​​智…

峰终定律——AI与思维模型【85】

一、定义 峰终定律思维模型是指人们对一段经历的评价主要取决于这段经历中的高峰时刻&#xff08;无论是正向的还是负向的&#xff09;以及结束时的感受&#xff0c;而不是整个经历的平均感受。也就是说&#xff0c;如果在一段体验的高峰和结尾阶段给人们留下积极、强烈的印象…

【补题】Codeforces Round 664 (Div. 1) A. Boboniu Chats with Du

题意&#xff1a;给出n&#xff0c;d&#xff0c;m三个值&#xff0c;分别代表&#xff0c;有多少个值ai&#xff0c;使用超过m的ai&#xff0c;需要禁言d天&#xff0c;如果不足也能使用&#xff0c;m代表区分点&#xff0c;问能得到最大的值有多少。 思路&#xff1a; …