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 注入。
    • 事务操作需确保提交或回滚,避免资源泄漏。
相关推荐
go_bai11 分钟前
Linux--常见工具
linux·开发语言·经验分享·笔记·vim·学习方法
ajassi200028 分钟前
开源 C# 快速开发(三)复杂控件
开发语言·开源·c#
郝学胜-神的一滴43 分钟前
深入理解前端 Axios 框架:特性、使用场景与最佳实践
开发语言·前端·程序人生·软件工程
jf加菲猫43 分钟前
条款11:优先选用删除函数,而非private未定义函数
开发语言·c++
歪歪1001 小时前
什么是TCP/UDP/HTTP?
开发语言·网络·网络协议·tcp/ip·http·udp
WangMing_X1 小时前
C#上位机软件:2.1 .NET项目解决方案的作用
开发语言·c#
博睿谷IT99_1 小时前
SQL SELECT 语句怎么用?COMPANY 表查询案例(含条件 / 模糊 / 分页)
数据库·sql·mysql
Pocker_Spades_A1 小时前
Python快速入门专业版(四十六):Python类的方法:实例方法、类方法、静态方法与魔术方法
开发语言·python
浅拾光º1 小时前
mysql字符串截取,如何在MySQL备份文件中安全截取敏感字符串?
数据库·mysql·安全
鸠摩智首席音效师1 小时前
如何删除 MySQL 数据库中的所有数据表 ?
数据库·mysql·oracle