Golang GORM ORM 基础
GORM ORM 基础核心概念GORM 是 Go 生态中最流行的 ORM 框架。它的设计哲学是用 Go 结构体描述数据库表用方法链表达查询逻辑让开发者用面向对象的方式操作数据库同时保留逃生通道Raw SQL。ORM vs Raw SQL// Raw SQLrows,_:db.Query(SELECT id, name, age FROM users WHERE age ? AND name LIKE ?,18,张%)// GORMvarusers[]User db.Where(age ? AND name LIKE ?,18,张%).Find(users)ORM 的价值在于结构体即表结构减少手写 SQL 的拼写错误、自动类型转换、关联查询自动化、迁移工具。代价是学习曲线和一定的性能损耗。连接与初始化import(gorm.io/gormgorm.io/driver/sqlite// 或 mysql, postgres)db,err:gorm.Open(sqlite.Open(test.db),gorm.Config{})GORM 的驱动层与database/sql不同它自己封装了连接管理但底层仍然可以接入*sql.DB。模型定义GORM 约定结构体名蛇形化为表名字段名蛇形化为列名。typeUserstruct{IDuintgorm:primaryKey// 主键Namestringgorm:size:100;not null// VARCHAR(100), NOT NULLEmailstringgorm:uniqueIndex// 唯一索引Ageintgorm:default:0// 默认值 0Birthday*time.Time// 指针类型 → 可 NULLCreatedAt time.Time// GORM 自动管理创建时间UpdatedAt time.Time// GORM 自动管理更新时间DeletedAt gorm.DeletedAtgorm:index// 软删除}约定优于配置Go 字段数据库列说明IDid名为 ID 的字段自动作为主键CreatedAtcreated_at记录创建时自动写入UpdatedAtupdated_at每次更新自动刷新DeletedAtdeleted_at软删除标记查询时自动过滤标签语法typeProductstruct{gorm.Model// 内嵌 ID CreatedAt UpdatedAt DeletedAtCodestringgorm:column:product_code;type:varchar(50);uniqueIndex:idx_codePriceuintgorm:check:price 0// CHECK 约束}常用标签column列名、type列类型、size长度、primaryKey、uniqueIndex、index、not null、default、comment、check。CRUD 操作Createuser:User{Name:张三,Email:zstest.com,Age:28}db.Create(user)// 插入并回填自增 ID// 批量插入db.Create([]User{{Name:李四,Email:lstest.com,Age:32},{Name:王五,Email:wwtest.com,Age:25},})// 选择性插入只写入指定字段db.Select(Name,Email).Create(User{Name:赵六,Email:zltest.com,Age:0})Read// 单条查询varuser User db.First(user,1)// 按主键db.First(user,email ?,zstest.com)// 按条件// 多条查询varusers[]User db.Find(users)// 全部db.Where(age ?,25).Find(users)// 条件db.Where(name LIKE ?,张%).Find(users)// 排序 分页db.Order(age DESC).Limit(10).Offset(0).Find(users)// 计数varcountint64db.Model(User{}).Where(age ?,20).Count(count)Update// 更新单个字段db.Model(user).Update(age,29)// 更新多个字段struct 方式零值字段会被忽略db.Model(user).Updates(User{Name:张三丰,Age:30})// 更新多个字段map 方式零值也会更新db.Model(user).Updates(map[string]interface{}{age:0,name:张三})// 批量更新db.Model(User{}).Where(age ?,25).Update(age,25)Delete// 软删除有 DeletedAt 字段时自动启用 db.Delete(user) // 设置 deleted_at now() db.Unscoped().Delete(user) // 真正删除 // 查询包含已软删除的记录 db.Unscoped().Find(users) // 批量删除 db.Where(age ?, 18).Delete(User{})链式调用与方法链GORM 的查询 API 是链式构建器模式方法分三类类型方法说明链式方法Where,Order,Limit,Select,Joins构建查询条件返回*gorm.DBFinisher 方法Find,First,Create,Update,Delete,Count触发执行新会话方法Session,WithContext,Scopes创建新会话上下文// 链式 Finisherdb.Where(age ?,20).Order(created_at DESC).Limit(20).Offset(0).Find(users)完整练习代码// gorm_basics.gopackagemainimport(fmtlogtimegorm.io/driver/sqlitegorm.io/gormgorm.io/gorm/logger)// User 用户模型typeUserstruct{IDuintgorm:primaryKeyNamestringgorm:size:100;not nullEmailstringgorm:size:200;uniqueIndexAgeintgorm:default:0Birthday*time.Time CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAtgorm:indexProducts[]Productgorm:foreignKey:UserID}// Product 产品模型演示外键关联typeProductstruct{IDuintgorm:primaryKeyNamestringPricefloat64Stockint// 一对多一个用户有多个产品UserIDuint// 外键User Usergorm:foreignKey:UserID// 关联}funcmain(){// 1. 连接数据库db,err:gorm.Open(sqlite.Open(:memory:),gorm.Config{Logger:logger.Default.LogMode(logger.Info),})iferr!nil{log.Fatal(err)}// 2. 自动迁移建表iferr:db.AutoMigrate(User{},Product{});err!nil{log.Fatal(err)}fmt.Println( 自动迁移完成 )// // 3. Create// fmt.Println(\n Create )// 单条插入birthday:time.Date(1998,5,15,0,0,0,0,time.UTC)user:User{Name:张三,Email:zstest.com,Age:28,Birthday:birthday}result:db.Create(user)fmt.Printf( 插入: ID%d, 影响行数%d\n,user.ID,result.RowsAffected)// 批量插入users:[]User{{Name:李四,Email:lstest.com,Age:32},{Name:王五,Email:wwtest.com,Age:25},{Name:赵六,Email:zltest.com,Age:35},{Name:孙七,Email:sqtest.com,Age:22},}db.Create(users)fmt.Printf( 批量插入: %d 条\n,len(users))// // 4. Read// fmt.Println(\n Read )// 按主键查询varu User db.First(u,1)fmt.Printf( First(1): %s, %d岁\n,u.Name,u.Age)// 条件查询varyoungUsers[]User db.Where(age ?,30).Order(age ASC).Find(youngUsers)fmt.Printf( age30 的用户 (%d人):\n,len(youngUsers))for_,yu:rangeyoungUsers{fmt.Printf( %s, %d岁\n,yu.Name,yu.Age)}// Select 指定字段varnames[]struct{NamestringAgeint}db.Model(User{}).Select(name,age).Where(age ?,28).Scan(names)fmt.Printf( age28 (SelectScan): )for_,n:rangenames{fmt.Printf(%s(%d) ,n.Name,n.Age)}fmt.Println()// 分页查询varpageUsers[]Uservartotalint64db.Model(User{}).Count(total)db.Limit(2).Offset(0).Order(id).Find(pageUsers)fmt.Printf( 分页(page1, size2): 共%d条, 本页%d条\n,total,len(pageUsers))// // 5. Update// fmt.Println(\n Update )// struct 更新零值字段被忽略db.Model(u).Updates(User{Name:张三丰,Age:30})fmt.Printf( Updates(struct): %s, %d岁\n,u.Name,u.Age)// map 更新零值也会更新db.Model(u).Updates(map[string]interface{}{age:0})db.First(u,u.ID)fmt.Printf( Updates(map): %s, %d岁 (age0 生效)\n,u.Name,u.Age)// 批量更新db.Model(User{}).Where(age ?,25).Update(age,25)varupdated[]User db.Where(age ?,25).Find(updated)fmt.Printf( 批量更新 age25 → age25: %d人\n,len(updated))// // 6. Delete软删除// fmt.Println(\n Delete软删除 )varzhao User db.Where(name ?,赵六).First(zhao)db.Delete(zhao)// 普通查询看不到已删除的varcountint64db.Model(User{}).Count(count)fmt.Printf( 删除赵六后剩余用户数: %d\n,count)// Unscoped 可以查到软删除的记录varallUsers[]User db.Unscoped().Find(allUsers)fmt.Printf( Unscoped 查询含软删除: %d条\n,len(allUsers))// // 7. 关联关系一对多// fmt.Println(\n 关联关系 )// 为张三创建产品db.Create(Product{Name:Go编程书,Price:89.5,Stock:100,UserID:1})db.Create(Product{Name:机械键盘,Price:459.0,Stock:50,UserID:1})db.Create(Product{Name:鼠标,Price:99.0,Stock:200,UserID:2})// 预加载查询避免 N1 问题varuserWithProducts User db.Preload(Products).First(userWithProducts,1)fmt.Printf( %s 的产品 (%d件):\n,userWithProducts.Name,len(userWithProducts.Products))for_,p:rangeuserWithProducts.Products{fmt.Printf( %s: %.2f (库存%d)\n,p.Name,p.Price,p.Stock)}// // 8. 钩子Hooks// fmt.Println(\n Hooks 演示 )// BeforeCreate 钩子会在插入前自动调用newUser:User{Name:测试钩子,Email:hooktest.com,Age:-1}db.Create(newUser)fmt.Printf( 创建前 Age-1, 创建后: %d (钩子修正了负数)\n,newUser.Age)}// BeforeCreate GORM 钩子插入前自动调用func(u*User)BeforeCreate(tx*gorm.DB)(errerror){// 年龄不能为负数自动修正为 0ifu.Age0{u.Age0}returnnil}运行方式mkdir-pdemo4cddemo4 go mod init demo4 go get gorm.io/gorm gorm.io/driver/sqlite go run main.go要点总结GORM 用结构体描述表标签控制列属性gorm.Model内嵌了 ID 时间戳 软删除四件套链式方法构建条件Finisher 方法触发执行链式方法返回*gorm.DB可继续链式调用struct Updates 零值被忽略需要更新零值时用map[string]interface{}软删除通过DeletedAt实现查询自动过滤Unscoped()可查已删除记录Preload 解决 N1 问题一条 SQL JOIN 加载关联数据避免循环查询Hooks 在生命周期点自动触发BeforeCreate/AfterCreate/BeforeUpdate/BeforeDelete等AutoMigrate 只增不减新增字段和表会自动创建但删除字段需要手动操作或用迁移工具

相关新闻

DDSP-SVC 版本对比:从 1.1 到 6.3 的歌声转换演进与选型完整指南

DDSP-SVC 版本对比:从 1.1 到 6.3 的歌声转换演进与选型完整指南

DDSP-SVC 版本对比:从 1.1 到 6.3 的歌声转换演进与选型完整指南 【免费下载链接】DDSP-SVC Real-time end-to-end singing voice conversion system based on DDSP (Differentiable Digital Signal Processing) 项目地址: https://gitcode.com/gh_mirrors/dd/DDS…

2026/8/23 21:34:13 阅读更多 →
把只读的 NTFS 硬盘变成 Mac 可写磁盘:Free-NTFS-for-Mac 完整指南

把只读的 NTFS 硬盘变成 Mac 可写磁盘:Free-NTFS-for-Mac 完整指南

把只读的 NTFS 硬盘变成 Mac 可写磁盘:Free-NTFS-for-Mac 完整指南 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and m…

2026/8/23 21:51:13 阅读更多 →
如何用ggVolcano包画出简单火山图

如何用ggVolcano包画出简单火山图

作为一名自来水用户,翻到了大佬自创R包画火山图,真正实现了一行代码画出火山图。👍👍👍 我花了10分钟学会了如何用,那就再花30分钟写一篇如何用吧。以此向大佬致敬。 一、安装和试用 #install.packages(…

2026/8/23 21:35:11 阅读更多 →

最新新闻

大模型算力治理实战:四层匹配体系与优化方案解析

大模型算力治理实战:四层匹配体系与优化方案解析

1. 从“算力焦虑”到“算力治理”:一个真实项目的起点最近两年,但凡跟大模型沾点边的项目,无论是内部研发还是对外交付,最常听到的抱怨就是“卡不够”。这背后,是大家普遍陷入的一种“算力焦虑”:模型稍微大…

2026/8/24 3:52:16 阅读更多 →
ComfyUI-Yolain-Workflows 电商产品主图:3步出图完整指南

ComfyUI-Yolain-Workflows 电商产品主图:3步出图完整指南

ComfyUI-Yolain-Workflows 电商产品主图:3步出图完整指南 【免费下载链接】ComfyUI-Yolain-Workflows Some awesome comfyui workflows in here, and they are built using the comfyui-easy-use node package. 项目地址: https://gitcode.com/gh_mirrors/co/Comf…

2026/8/24 3:52:16 阅读更多 →
STM32 GPIO驱动三极管电路:从模式配置到实战设计指南

STM32 GPIO驱动三极管电路:从模式配置到实战设计指南

1. 项目概述:从GPIO到三极管,构建稳定可靠的数字接口 在嵌入式开发,尤其是基于STM32这类MCU的项目中,GPIO(通用输入输出)的配置是每个开发者都绕不开的第一步。但很多新手,甚至一些有经验的工程…

2026/8/24 3:52:16 阅读更多 →
Java后端面试突击:两周系统备战高并发与JVM调优

Java后端面试突击:两周系统备战高并发与JVM调优

对于 Java 后端开发者来说,每年九、十月份的招聘旺季既是机会也是挑战。企业释放大量岗位,但竞争同样激烈,面试官的问题也从基础语法延伸到高并发、JVM 调优、系统设计等深度场景。如果准备不足,很容易在技术面环节暴露知识盲区。…

2026/8/24 3:52:16 阅读更多 →
Edge浏览器插件更新全流程实战:从原理到私有化部署

Edge浏览器插件更新全流程实战:从原理到私有化部署

最近在折腾Edge浏览器插件开发时,发现一个挺普遍但容易被忽略的问题:插件更新机制。很多开发者,包括我自己,都曾遇到过用户反馈“插件怎么还是旧版本”、“自动更新好像没生效”的情况。这背后涉及到Edge插件(基于Chro…

2026/8/24 3:52:16 阅读更多 →
如何三步跑通 Java RMI 漏洞扫描:remote-method-guesser 完整指南

如何三步跑通 Java RMI 漏洞扫描:remote-method-guesser 完整指南

如何三步跑通 Java RMI 漏洞扫描:remote-method-guesser 完整指南 【免费下载链接】remote-method-guesser Java RMI Vulnerability Scanner 项目地址: https://gitcode.com/gh_mirrors/re/remote-method-guesser remote-method-guesser(简称 rmg…

2026/8/24 3:51:16 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力;确需渲染 HTML 时,先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述:Windows登录密码的“黑匣子”每次你按下CtrlAltDel,输入密码,然后看到那个熟悉的桌面,这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者,我经常被问到:“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述:AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时,遇到一个典型案例:候选人在视频面试中无意提到竞争对手产品名称,系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/22 3:22:48 阅读更多 →