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 注入。
    • 事务操作需确保提交或回滚,避免资源泄漏。
相关推荐
月忆3647 分钟前
Etcd原理基础学习
分布式·golang
overFitBrain25 分钟前
数据结构-5(二叉树)
开发语言·数据结构·python
rookiesx36 分钟前
安装本地python文件到site-packages
开发语言·前端·python
m0_687399841 小时前
Ubuntu22 上,用C++ gSoap 创建一个简单的webservice
开发语言·c++
屁股割了还要学1 小时前
【C语言进阶】一篇文章教会你文件的读写
c语言·开发语言·数据结构·c++·学习·青少年编程
微露清风1 小时前
系统性学习C语言-第二十二讲-动态内存管理
c语言·开发语言·学习
钮钴禄·爱因斯晨1 小时前
C语言|指针的应用
c语言·开发语言
火凤凰--凤凰码路1 小时前
MySQL 中的“双路排序”与“单路排序”:原理、判别与实战调优
android·数据库·mysql
Shingmc31 小时前
【C++】二叉搜索数
开发语言·c++
一个天蝎座 白勺 程序猿2 小时前
Python(32)Python内置函数全解析:30个核心函数的语法、案例与最佳实践
android·开发语言·python