Gin 不处理数据库连接,需用 database/sql 配 MySQL 驱动;sql.Open 仅校验 DSN,须 db.Ping() 测试连通;*sql.DB 应挂载到 Gin 上供 handler 使用;Query 返回的 rows 必须显式 Close() 防泄漏;QueryRow 自动关闭;Scan 须严格匹配字段顺序、类型及 NULL 处理;事务中必须统一使用 tx 对象,避免混用 db 和 tx。
Go Gin 里用
连 MySQL,不是用 Gin 自己连
Gin 本身不处理数据库连接,它只管 HTTP 路由和响应。真正连 MySQL 的是 Go 标准库
,配合 MySQL 驱动(比如
)。很多人卡在第一步:以为 Gin 提供了
这种方法,其实没有。
实操建议:
先
安装驱动
用
初始化连接池,注意参数里
和
要加,否则
字段可能解析失败或时区错乱
别忘了调
检查连通性,
只校验 DSN 格式,不真正建连
把
实例挂到 Gin 的
上,常用方式是
,后续 handler 里用
取
Query 和 QueryRow 返回的
必须显式
这是最常被忽略的资源泄漏点。Gin handler 里写
后,如果没调
,连接会一直占着,很快耗尽连接池(尤其高并发时)。
常见错误现象:
立即学习
“
go语言免费学习笔记(深入)
”;
请求变慢、超时,日志里出现
MySQL 侧看到大量
状态连接
正确做法:
用
—— 但注意:必须在
循环结束后再 defer,否则循环中途就关了
更稳妥的是把
放在 for 循环之后、函数 return 前,或者用
包一层
不需要手动 Close,它内部自动处理
用
读数据时,变量顺序、类型、数量必须和 SELECT 字段严格一致
MySQL 查询字段顺序变了、加了新字段、用了别名但没对应上变量,
就会直接 panic 或静默失败(比如把 int 扫成 string),而且错误信息往往不明确。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
使用场景举例:你写
,那
三个变量顺序不能错,且
类型得是
(前提是 DSN 里开了
)。
容易踩的坑:
SELECT 里用了函数或表达式(如
),结果类型是
,但你还用
变量去 Scan → panic
字段有 NULL,但用非指针类型接收(如
而非
)→
用
,表结构一变,代码立刻崩,别这么干
事务里别混用
和
一旦开始事务(
),所有操作必须走
对象,比如
、
。如果在事务中误用了
,那这条语句根本不在事务里,也不会受
或
控制。
性能与一致性影响:
看似成功提交,其实部分数据已落库(
那条),事务原子性彻底失效
调试时很难发现,因为没报错,只是逻辑错乱
实操建议:
事务内统一用
;handler 函数开头就判断是否在事务上下文里(比如通过
),避免混用
事务结束前,记得
或
,后者尤其重要——panic 或 error 时没 rollback,连接就卡死在事务中
别依赖 defer 做 rollback:
在 Commit 成功后也会执行,导致二次 rollback 报错
真正的难点不在语法,而在连接生命周期管理、资源释放时机、事务边界控制这些“看不见”的地方。写完一行
,得立刻想清楚:它什么时候关?在哪关?会不会和其他操作串了?
database/sqldatabase/sqlgithub.com/go-sql-driver/mysqlgin.DB()go get github.com/go-sql-driver/mysqlsql.Open("mysql", "user:pass@tcp(127.0.0.1:3306)/dbname?parseTime=true&loc=Local")parseTime=trueloc=Localtime.Timedb.Ping()sql.Open*sql.DBgin.Engineengine.Use(func(c *gin.Context) { c.Set("db", db) })c.MustGet("db").(*sql.DB)sql.RowsClose()rows, err := db.Query("SELECT ...")rows.Close()dial tcp 127.0.0.1:3306: connect: cannot assign requested addressSleepdefer rows.Close()for rows.Next()rows.Close()if rows != nil { defer rows.Close() }QueryRowScanScan()SELECT id, name, created_at FROM usersScan(&id, &name, &createdAt)createdAttime.TimeparseTime=trueUNIX_TIMESTAMP(created_at)int64time.Timestring*stringsql: Scan error on column index 1SELECT *db.Querytx.Querytx, _ := db.Begin()txtx.Querytx.Execdb.Querytx.Commit()tx.Rollback()db.Querytxc.Get("tx")tx.Commit()tx.Rollback()defer tx.Rollback()db.Query