必须先调用sql.Open获取*sql.DB但不立即建连,首次Query/Exec才触发连接;需导入驱动、检查Open和Ping的error;Query用于多行、QueryRow用于单行;Exec执行增删改并获取结果;事务须显式Commit/Rollback。
如何用
连接数据库并执行查询
必须先调用
获取
,但它不立即建连;真正触发连接的是第一次执行查询(如
或
)。常见错误是忽略返回的
,导致后续操作 panic。
的第一个参数是驱动名(如
、
),需提前导入对应驱动(如
)
第二个参数是数据源字符串(DSN),格式因驱动而异:
务必调用
主动验证连接是否可用,否则首次查询失败时才暴露问题
和
的区别与选用场景
用于返回多行结果(如 SELECT 多条记录),返回
;
专为「预期只有一行」设计(如 SELECT ... LIMIT 1 或
聚合函数
),自动调用
并处理
。
用
时,即使 SQL 本意是查一行,若实际无结果,
会返回
,不是
必须显式调用
,否则连接不会归还到连接池——这是最常被漏掉的资源泄漏点
不要对同一
多次调用
;每次
移动游标,需在循环中配对使用
插入、更新、删除必须用
,不能用
专门处理不返回结果集的操作(INSERT/UPDATE/DELETE),它返回
,可获取影响行数或最后插入 ID;用
执行这类语句虽可能不报错,但会浪费连接、阻塞连接池,且无法获取执行结果。
不支持查询缓存,也不走查询分析器优化路径,纯命令执行
获取自增 ID 要用
,但注意:SQLite 和某些 MySQL 配置下该值可能不可靠,PostgreSQL 则根本不支持,得改用
子句配合
批量插入别拼 SQL 字符串,用
占位符 + 多参数传入,避免 SQL 注入和语法错误
事务处理必须显式
或
返回的
是独立连接,所有操作都绑定在其上;忘记
或
会导致连接长期占用、锁表、甚至连接池耗尽。
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数组安全、编译
下载
立即学习
“
go语言免费学习笔记(深入)
”;
推荐用
开头,再在成功路径末尾
—— 这样能确保无论中间哪步出错,事务都会回滚
事务内不能再用原始
执行语句,否则会脱离事务上下文
事务超时由驱动和数据库决定,
本身不提供超时控制,需靠上下文(
)传入
事务的边界容易被忽视:比如在函数里开了事务,但调用方没处理 panic,
就不会触发
;更稳妥的做法是把
放在 recover 之后,或者统一用带 context 的
配合超时兜底。
database/sqlsql.Open*sql.DBQueryExecerrorsql.Open"mysql""postgres"_ "github.com/go-sql-driver/mysql""user:pass@tcp(127.0.0.1:3306)/dbname?parseTime=true"db.Ping()db, err := sql.Open("mysql", "root:@tcp(localhost:3306)/test")
if err != nil {
log.Fatal(err)
}
if err := db.Ping(); err != nil {
log.Fatal("failed to connect:", err)
}QueryQueryRowQuery*sql.RowsQueryRowScansql.ErrNoRowsQueryRowScansql.ErrNoRowsnilQueryrows.Close()*sql.RowsScanNext()var name string
err := db.QueryRow("SELECT name FROM users WHERE id = ?", 123).Scan(&name)
if err == sql.ErrNoRows {
// 处理未找到
} else if err != nil {
// 处理其他错误
}ExecQueryExecsql.ResultQueryExecresult.LastInsertId()RETURNINGQueryRowVALUES (?, ?), (?, ?)res, err := db.Exec("INSERT INTO users(name, email) VALUES(?, ?)", "Alice", "a@example.com")
if err != nil {
log.Fatal(err)
}
id, _ := res.LastInsertId() // 注意:PostgreSQL 不适用CommitRollbackdb.Begin()*sql.TxCommitRollbackdefer tx.Rollback()tx.Commit()*sql.DBdatabase/sqlcontext.WithTimeoutBeginTxtx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", 100, 1)
if err != nil {
return err
}
return tx.Commit()
deferRollbackRollbackBeginTx