golang中的标准库database/sql 包为SQL和类SQL数据库的操作提供了通用的接口。
database/sql 包 必须与数据库driver 配套使用。
目前已有的SQL database drivers 见链接。
这里面就包括比较常用的MySQL driver go-sql-driver/mysql 。
database/sql 包的设计可以说是很巧妙。
它对于上层应用提供了标准的API接口,对下层驱动driver暴露了简单的驱动接口。
并且实现了连接池的管理。这意味着,不同数据库的驱动只需要实现驱动接口,不需要关心连接池的实现细节。
常用的API操作接口
连接数据库
db, err := sql.Open(driver, dataSourceName)
连接MySQL,这里driver就是"mysql".
dataSourceName 定义了具体的连接参数。
执行SQL
ExecContext 常用执行没有rows返回的场景。
例如新建、删除
result, err := db.ExecContext(ctx,
"INSERT INTO users (name, age) VALUES ($1, $2)",
"gopher",
27,
)
QueryContext 常用于查询数据集rows。
例如,查询select
rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age = $1", age)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
QueryRowContext 用于查询一条记录。
var age int64
err := db.QueryRowContext(ctx, "SELECT age FROM users WHERE name = $1", name).Scan(&age)
Prepared statements可以防止sql注入。
age := 27
stmt, err := db.PrepareContext(ctx, "SELECT name FROM users WHERE age = $1")
if err != nil {
log.Fatal(err)
}
rows, err := stmt.Query(age)
// process rows
在一个statements上,也可以执行ExecContext, QueryContext and QueryRowContext 。
statements使用完后,需要Close。
事务Transactions
可以使用以下方式开始一个事务Transactions:
tx, err := db.BeginTx(ctx, nil)
if err != nil {
log.Fatal(err)
}
在一个事务Transactions上,可以执行ExecContext, QueryContext, QueryRowContext 以及PrepareContext。
一个Transactions的结束,或者调用 Commit 或者调用 Rollback。
NULL的处理
sql.NullString 类型可用于处理字段值为NULL的情况。
如果name字段值可能为null,可以这样处理:
var name sql.NullString
err := db.QueryRowContext(ctx, "SELECT name FROM names WHERE id = $1", id).Scan(&name)
...
if name.Valid {
// use name.String
} else {
// value is NULL
}
标准库 database/sql 目前支持NullBool, NullFloat64, NullInt64, NullInt32, NullString and NullTime 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现