GORM通过结构体定义模型、自动迁移创建表、提供链式API进行CRUD操作,并支持连接池配置与错误排查。使用GORM需先连接数据库,定义如User等结构体模型,利用AutoMigrate建表,再通过Create、First、Save、Delete等方法实现数据操作,同时可通过标签自定义字段映射,结合Preload处理关联关系,结合事务保证数据一致性。

直接上手就能跑通,Fiber + GORM 的增删改查集成没有额外抽象层,核心就是把 gorm.DB 实例安全地注入到 Fiber 的 ctx 或 handler 作用域里,而不是每次请求都重连。
怎么把 GORM 连接传进 Fiber handler
Fiber 本身不管理数据库连接生命周期,你得自己控制初始化和复用。常见错误是:在每个 handler 里调用 gorm.Open(),导致连接泄漏、端口耗尽或认证失败。
- 全局单例初始化
gorm.DB,并在app.Use()中挂载为上下文值(推荐) - 用
app.Get("/user", func(c *fiber.Ctx) error { db := c.Locals("db").(*gorm.DB) ... })取出使用 - 别用闭包捕获
db变量——Fiber 的 handler 是并发执行的,但gorm.DB本身是并发安全的,只要不是反复 Open - 记得调用
db.DB().SetMaxOpenConns()和db.DB().SetMaxIdleConns(),否则 PostgreSQL/MySQL 默认连接池极小,高并发下直接卡死
PostgreSQL 连接字符串写错会卡在 Ping 阶段
用 postgres 驱动时,host、port、user、password、dbname 缺一不可,且顺序无关,但参数名必须拼写正确。常见错误现象是:context deadline exceeded 或长时间无响应。
- 检查
host是否写成127.0.0.1却忘了 PostgreSQL 的pg_hba.conf没开 trust 或 md5 认证 -
port默认是5432,但 Docker 或云服务常映射到其他端口,务必核对docker ps或服务商控制台 - 连接字符串中不要加
sslmode=disable以外的 SSL 参数,除非你真配了证书;本地开发建议显式加sslmode=disable避免握手失败 - 示例安全 DSN:
host=localhost port=5432 user=postgres password=mypassword dbname=mydb sslmode=disable
GORM 查询时 Find() 和 First() 的行为差异
这两个方法底层 SQL 不同,也影响空结果处理逻辑,容易在 Fiber 返回 JSON 时 panic。
-
db.First(&u, 1)查不到会返回gorm.ErrRecordNotFound,u字段保持零值 —— 适合“查单条必须存在”的场景 -
db.Find(&users)查不到则users是空切片,不会报错 —— 适合列表接口,直接c.JSON(200, users)安全 - 别对
First()的结果直接取指针字段,比如u.Name前没判 err,会导致空结构体序列化出错字段 - 如果想统一处理“未找到”,用
db.Where("id = ?", id).First(&u)+errors.Is(err, gorm.ErrRecordNotFound)
软删除 + Unscoped 在 Fiber 接口中怎么用才不翻车
电商、后台系统常需要“回收站”功能,但 Unscoped() 是全局开关,一不小心就让所有查询绕过软删除逻辑。
- 只在明确需要查已删除数据的路由里用
db.Unscoped().Where(...).Find(),比如GET /admin/products/trash - 千万别在中间件里全局
db = db.Unscoped(),否则所有业务查询失效 - 物理删除(真正从磁盘删)必须加二次确认,例如
DELETE /products/:id?hard=true,然后 handler 里写db.Unscoped().Delete(&p) - 软删除字段名必须是
DeletedAt gorm.DeletedAt,不能自定义成IsDeleted bool—— 否则Unscoped()不生效
最易被忽略的是连接池配置和软删除的边界控制:前者导致上线后扛不住压测,后者导致用户看到“已下架商品”却查不到,或者更糟——把不该删的数据真删了。











