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 注入。
    • 事务操作需确保提交或回滚,避免资源泄漏。
相关推荐
小羽网安17 分钟前
从零开始学习 sql 注入,常见的 sql 注入解析
数据库·sql·学习
2401_846339561 小时前
CSS如何优化大型项目样式_使用SASS预处理器提升开发效率
jvm·数据库·python
Gofarlic_oms16 小时前
利用API实现ANSYS许可证管理自动化集成
运维·服务器·开发语言·matlab·自动化·负载均衡
AI+程序员在路上7 小时前
VS Code 完全使用指南:下载、安装、核心功能与 内置AI 编程助手实战
开发语言·人工智能·windows·开源
invicinble7 小时前
这里对java的知识体系做一个全域的介绍
java·开发语言·python
catchadmin7 小时前
使用 PHP TrueAsync 改造 Laravel 协程异步化的可行路径
开发语言·php·laravel
wbs_scy7 小时前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·开发语言
ss2737 小时前
食谱推荐系统功能测试如何写?
java·数据库·spring boot·功能测试
AI人工智能+电脑小能手8 小时前
【大白话说Java面试题】【Java基础篇】第15题:JDK1.7中HashMap扩容为什么会发生死循环?如何解决
java·开发语言·数据结构·后端·面试·哈希算法
l1t8 小时前
DeepSeek总结的数据库外部表
数据库