应使用 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 官方没有内置 MySQL 驱动,必须手动引入第三方驱动。最常用、维护最活跃的是
。别被名字误导——它不叫
,直接
会失败或装错包。
正确命令是:
注意:Go 1.21+ 默认启用 Go Module,无需额外初始化;若项目无
,先运行
。
不要用已归档的
或过时的
(不存在)
如果遇到
,说明 Go 环境异常,检查
和
是否污染
该驱动纯 Go 实现,无需 C 编译器,Windows/macOS/Linux 均可直接用
配置 DSN:用户名、密码、地址不能裸写,要 URL
编码
连接字符串(DSN)格式为:
。其中
是 URL 查询参数分隔符,必须用
(HTML 实体),不能写成
,否则解析失败。
立即学习
“
go语言免费学习笔记(深入)
”;
常见坑点:
Docker Sandbox
创建并管理 Docker 沙箱虚拟机环境以安全执行代理。适用于运行不受信任代码、探索包或隔离代理工作负载。支持 Claude、Codex、Copilot、Gemini 和 Kiro 代理,并提供网络代理控制。
下载
密码含特殊字符(如
、
、
)必须用
编码,否则 DSN 解析错位
才能让
正确扫描 DATETIME 字段;不加会导致 scan 错误或返回零值时间
避免时区混乱(尤其 Docker 容器里默认 UTC),也可设为
(需 URL 编码)
数据库名在 DSN 中是可选的,但
不校验连通性,真正报错在第一次
或查询时
初始化
:别漏掉
和连接池配置
只是创建句柄,不建立物理连接。必须显式调用
来验证是否能连上 MySQL,否则错误会延迟到后续查询才暴露。
推荐初始化写法:
连接池相关设置直接影响并发表现:
:最大打开连接数,过高可能压垮 MySQL(默认 0 = 无限制)
:空闲连接上限,避免连接泄漏(默认 2)
:连接最长复用时间,防止 MySQL 的
中断长连接
执行查询时:用
/
而非
处理单行或无结果操作
很多初学者对
过度谨慎,哪怕只查一行也用
+
+
,其实大可不必。
查单行且必有结果 → 用
,自动处理
错误
执行 INSERT/UPDATE/DELETE 且不关心影响行数 → 用
;若需获取影响行数,用
只有明确需要遍历多行(比如分页拉取、导出全量)才用
,且务必记得
所有
的变量地址必须传对,类型要和列一致(例如
列不能直接 Scan 到
)
MySQL 驱动对
值敏感,字段可能为 NULL 时,要用
等类型承接,否则 Scan 会报
。
go-sql-driver/mysqlmysqlgo-sql-driver/mysqlmysqlgo get mysqlgo get -u github.com/go-sql-driver/mysqlgo.modgo mod init your-project-namegithub.com/ziutek/mymysqldatabase/mysqlcannot find package "database/sql"GOROOTGOPATHuser:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local&&&@/:url.QueryEscape()parseTime=Truetime.Timeloc=Localloc=Asia%2FShanghaisql.Open()db.Ping()*sql.DBdb.Ping()sql.Open()db.Ping()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)db.SetMaxIdleConns(10)db.SetConnMaxLifetime(60 * time.Second)wait_timeoutQueryRow()Exec()Query()*sql.RowsQuery()rows.Next()rows.Scan()db.QueryRow(sql, args...).Scan(&v1, &v2)NoRowsdb.Exec()result, _ := db.Exec(...); rows, _ := result.RowsAffected()db.Query()defer rows.Close()Scan()INTstringNULLsql.NullStringsql: Scan error on column index 0