应使用 go-sql-driver/mysql 驱动,执行 go get -u github.com/go-sql-driver/mysql;DSN 需 URL 编码,含 parseTime=True 和 loc=Local;sql.Open() 后须调用 db.Ping() 验证连接,并合理配置连接池。

安装 MySQL 驱动:用 go-sql-driver/mysql 而不是 mysql
Go 官方没有内置 MySQL 驱动,必须手动引入第三方驱动。最常用、维护最活跃的是 go-sql-driver/mysql。别被名字误导——它不叫 mysql,直接 go get mysql 会失败或装错包。
正确命令是:
go get -u github.com/go-sql-driver/mysql
注意:Go 1.21+ 默认启用 Go Module,无需额外初始化;若项目无 go.mod,先运行 go mod init your-project-name。
- 不要用已归档的
github.com/ziutek/mymysql或过时的database/mysql(不存在) - 如果遇到
cannot find package "database/sql",说明 Go 环境异常,检查GOROOT和GOPATH是否污染 - 该驱动纯 Go 实现,无需 C 编译器,Windows/macOS/Linux 均可直接用
配置 DSN:用户名、密码、地址不能裸写,要 URL 编码
连接字符串(DSN)格式为:user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local。其中 & 是 URL 查询参数分隔符,必须用 &(HTML 实体),不能写成 &,否则解析失败。
立即学习“go语言免费学习笔记(深入)”;
常见坑点:
- 密码含特殊字符(如
@、/、:)必须用url.QueryEscape()编码,否则 DSN 解析错位 -
parseTime=True才能让time.Time正确扫描 DATETIME 字段;不加会导致 scan 错误或返回零值时间 -
loc=Local避免时区混乱(尤其 Docker 容器里默认 UTC),也可设为loc=Asia%2FShanghai(需 URL 编码) - 数据库名在 DSN 中是可选的,但
sql.Open()不校验连通性,真正报错在第一次db.Ping()或查询时
初始化 *sql.DB:别漏掉 db.Ping() 和连接池配置
sql.Open() 只是创建句柄,不建立物理连接。必须显式调用 db.Ping() 来验证是否能连上 MySQL,否则错误会延迟到后续查询才暴露。
推荐初始化写法:
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
defer db.Close() // 注意:Close() 是释放资源,不是关闭单次连接
if err = db.Ping(); err != nil {
log.Fatal("failed to connect:", err)
}
连接池相关设置直接影响并发表现:
-
db.SetMaxOpenConns(20):最大打开连接数,过高可能压垮 MySQL(默认 0 = 无限制) -
db.SetMaxIdleConns(10):空闲连接上限,避免连接泄漏(默认 2) -
db.SetConnMaxLifetime(60 * time.Second):连接最长复用时间,防止 MySQL 的wait_timeout中断长连接
执行查询时:用 QueryRow() / Exec() 而非 Query() 处理单行或无结果操作
很多初学者对 *sql.Rows 过度谨慎,哪怕只查一行也用 Query() + rows.Next() + rows.Scan(),其实大可不必。
- 查单行且必有结果 → 用
db.QueryRow(sql, args...).Scan(&v1, &v2),自动处理NoRows错误 - 执行 INSERT/UPDATE/DELETE 且不关心影响行数 → 用
db.Exec();若需获取影响行数,用result, _ := db.Exec(...); rows, _ := result.RowsAffected() - 只有明确需要遍历多行(比如分页拉取、导出全量)才用
db.Query(),且务必记得defer rows.Close() - 所有
Scan()的变量地址必须传对,类型要和列一致(例如INT列不能直接 Scan 到string)
MySQL 驱动对 NULL 值敏感,字段可能为 NULL 时,要用 sql.NullString 等类型承接,否则 Scan 会报 sql: Scan error on column index 0。










