Go连接MySQL最稳妥方式是database/sql加go-sql-driver/mysql驱动;需显式导入驱动,正确配置连接字符串,区分Query/QueryRow/Exec用途,仅用?占位防注入,手动管理事务,并显式设置连接池参数。
Go 语言连接 MySQL 最稳妥的方式是用 database/sql + github.com/go-sql-driver/mysql,不是 ORM,也不是封装层,而是标准接口+专用驱动的组合——它不隐藏细节,出错时你能直接看到 SQL 执行链路上哪一环断了。
安装驱动并建立基础连接
Go 没有内置 MySQL 驱动,必须显式引入第三方驱动。仅导入 database/sql 是不够的,会 panic:”sql: unknown driver ‘mysql'”。
- 运行
go get -u github.com/go-sql-driver/mysql - 在代码中同时导入:
"database/sql"和"github.com/go-sql-driver/mysql"(后者仅需导入,无需赋值或调用) - 连接字符串格式为:
"user:password@tcp(127.0.0.1:3306)/dbname?parseTime=true&loc=Local";注意&是 URL 中的 & 字符,不能写成& -
parseTime=true让驱动把DATETIME/TIMESTAMP自动转成time.Time;loc=Local避免时区错乱(否则可能默认 UTC)
Query、QueryRow 与 Exec 的分工
这三个方法不 interchangeable:选错会导致死锁、漏扫描、或误吞错误。
-
db.Query()用于 SELECT 多行,返回*sql.Rows,**必须调用rows.Close()**(哪怕只读一行),否则连接不会释放 -
db.QueryRow()用于确定只返回一行的 SELECT(如带 LIMIT 1 或主键查询),它内部自动 Close,但你要用.Scan()拿数据,否则 Scan 错误会被静默丢弃 -
db.Exec()用于 INSERT/UPDATE/DELETE,返回sql.Result,可调.LastInsertId()和.RowsAffected();**不能用它执行 SELECT**,否则返回空结果且无报错
防止 SQL 注入:只用问号占位符,不用字符串拼接
MySQL 驱动不支持命名参数(如 :name 或 @id),只认 ?,且参数必须是切片或单独值,不能是 map 或结构体。