Skip to main content

Go: 标准库 database

📅 2026-03-13 ✏️ 2026-03-23 Go 标准库 CS GO
No related notes

1 · 标准库 database#

1.1 · 核心设计

database/sql 包的核心思想:用户代码只依赖 sql 包,驱动实现 driver 接口,两者通过注册机制连接。

                调用            调用接口
  用户代码 ───────────► sql包 ───────────► driver包
                         ▲                   ▲
                    注册 │        实现接口    │
                         └──── 驱动实现 ──────┘

好处:

  1. sql 包统一处理 Go 类型与 DB 类型转换,驱动只处理小部分类型
  2. sql 包内置连接池,并发安全,sql.DB 可在多个 goroutine 间共享
  3. 复杂度封装在 sql/driver 内,不暴露给用户

1.2 · sql.DB — 不是连接,是连接池#

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql" // 驱动 init() 中调用 sql.Register 注册
)

// Open 只验证参数,不创建连接(延迟连接)
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
defer db.Close()

1.3 · 三个核心操作

1.3.1 · 查询 — Query → Rows → Scan#

rows, err := db.QueryContext(ctx, "SELECT id, name FROM users WHERE id = ?", 1)
defer rows.Close()
for rows.Next() {
	var id int
	var name string
	rows.Scan(&id, &name)
}
err = rows.Err() // 检查迭代中的错误

1.3.2 · 修改 — Exec → Result#

result, err := db.ExecContext(ctx, "INSERT INTO users(name) VALUES(?)", "Dolly")
lastID, _ := result.LastInsertId()
affected, _ := result.RowsAffected()

1.3.3 · 事务 — Begin → Tx → Commit/Rollback#

tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
_, err = tx.Exec(`UPDATE users SET status = ? WHERE id = ?`, "paid", 37)
if err != nil {
	tx.Rollback()
	return
}
tx.Commit()

事务期间绑定一个连接,Commit/Rollback 后连接回归空闲池。

1.4 · driver 包 — 核心接口层次#

        Driver


        Conn
        ▲   ▲
        │   │
      Tx    Stmt
            ▲  ▲
            │  │
        Result  Rows
接口职责
Driver / DriverContext打开连接
Connector带 context 创建连接
ConnPrepare, Close, Begin
StmtExec, Query, Close
RowsColumns, Next, Close
ResultLastInsertId, RowsAffected
TxCommit, Rollback

1.5 · 所学

面向接口编程 — 只依赖抽象的接口,不依赖具体的实现。


1.5.1 · 更多阅读

  1. https://go.dev/src/database/sql/doc.txt
  2. http://go-database-sql.org/