Go 语言标准库中database模块详细功能介绍与示例

Go语言的标准库 database/sql 提供了与 SQL 数据库交互的通用接口,但需要搭配具体的数据库驱动(如 MySQL、PostgreSQL 等)使用。以下是 database/sql 的核心方法及示例说明:


1. 连接数据库

sql.Open(driverName, dataSourceName)

连接数据库并返回 *sql.DB 对象(需先注册驱动)。

go 复制代码
import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql" // 匿名导入MySQL驱动
)

func main() {
    // 数据源格式:用户名:密码@协议(地址:端口)/数据库名?参数
    db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/testdb")
    if err != nil {
        panic(err)
    }
    defer db.Close() // 确保关闭连接
}

2. 检查连接

DB.Ping()

验证数据库连接是否有效。

go 复制代码
err = db.Ping()
if err != nil {
    panic("数据库连接失败: " + err.Error())
}

3. 执行查询

DB.Query()

执行查询语句并返回多行结果(*sql.Rows)。

go 复制代码
rows, err := db.Query("SELECT id, name FROM users WHERE age > ?", 18)
if err != nil {
    panic(err)
}
defer rows.Close() // 必须关闭Rows释放资源

for rows.Next() {
    var id int
    var name string
    err = rows.Scan(&id, &name)
    if err != nil {
        panic(err)
    }
    fmt.Printf("ID: %d, Name: %s\n", id, name)
}
if err = rows.Err(); err != nil {
    panic(err)
}

4. 执行单行查询

DB.QueryRow()

执行查询并返回单行结果(*sql.Row)。

go 复制代码
var name string
err = db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)
if err != nil {
    if err == sql.ErrNoRows {
        fmt.Println("未找到记录")
    } else {
        panic(err)
    }
}
fmt.Println("用户名:", name)

5. 执行非查询操作

DB.Exec()

执行插入、更新或删除操作,返回 sql.Result

go 复制代码
result, err := db.Exec(
    "INSERT INTO users (name, age) VALUES (?, ?)",
    "Alice", 30,
)
if err != nil {
    panic(err)
}

lastInsertID, _ := result.LastInsertId() // 获取自增ID
rowsAffected, _ := result.RowsAffected() // 获取影响行数
fmt.Printf("插入ID: %d, 影响行数: %d\n", lastInsertID, rowsAffected)

6. 预处理语句

DB.Prepare()

创建预处理语句(防止SQL注入,提升性能)。

go 复制代码
stmt, err := db.Prepare("UPDATE users SET age = ? WHERE id = ?")
if err != nil {
    panic(err)
}
defer stmt.Close()

_, err = stmt.Exec(31, 1) // 更新ID为1的用户的年龄
if err != nil {
    panic(err)
}

7. 事务处理

DB.Begin()

开启事务,返回 *sql.Tx 对象。

go 复制代码
tx, err := db.Begin()
if err != nil {
    panic(err)
}

// 在事务中执行操作
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", 100, 1)
if err != nil {
    tx.Rollback() // 回滚事务
    panic(err)
}

_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", 100, 2)
if err != nil {
    tx.Rollback()
    panic(err)
}

err = tx.Commit() // 提交事务
if err != nil {
    panic(err)
}

8. 连接池配置

DB.SetMaxOpenConns(n)DB.SetMaxIdleConns(n)

设置最大打开连接数和最大空闲连接数。

go 复制代码
db.SetMaxOpenConns(25)   // 最大并发连接数
db.SetMaxIdleConns(10)   // 最大空闲连接数
db.SetConnMaxLifetime(time.Hour) // 连接最大存活时间

总结

  • 核心方法
    • 连接管理sql.Open, DB.Ping, DB.Close
    • 查询操作DB.Query, DB.QueryRow, Rows.Scan
    • 非查询操作DB.Exec, Result.LastInsertId, Result.RowsAffected
    • 预处理与事务DB.Prepare, DB.Begin, Tx.Commit, Tx.Rollback
    • 连接池配置SetMaxOpenConns, SetMaxIdleConns
  • 注意事项
    • 必须导入具体的数据库驱动(如 github.com/go-sql-driver/mysql)。
    • 始终检查错误并释放资源(如 rows.Close(), stmt.Close())。
    • 使用预处理语句防止 SQL 注入。
    • 事务操作需确保提交或回滚,避免资源泄漏。
相关推荐
全栈老石2 小时前
拆解低代码引擎核心:元数据驱动的"万能表"架构
数据库·低代码
倔强的石头_21 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
花酒锄作田5 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1235 天前
matlab画图工具
开发语言·matlab
加号35 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql