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 注入。
    • 事务操作需确保提交或回滚,避免资源泄漏。
相关推荐
xyliiiiiL38 分钟前
从责任链模式聊到aware接口
java·开发语言
Elec_z2 小时前
网络深处的守门人
开发语言·网络
闪电麦坤953 小时前
C#:Time.deltaTime
开发语言·c#
影子24014 小时前
Navicat导出mysql数据库表结构说明到excel、word,单表导出方式记录
数据库·mysql·excel
java_heartLake4 小时前
PostgreSQL15深度解析(从15.0-15.12)
数据库·postgresql
Alfadi联盟 萧瑶5 小时前
Python-Django入手
开发语言·python·django
-代号95276 小时前
【JavaScript】十二、定时器
开发语言·javascript·ecmascript
勘察加熊人6 小时前
c++实现录音系统
开发语言·c++
self-discipline6346 小时前
【Java】Java核心知识点与相应面试技巧(七)——类与对象(二)
java·开发语言·面试
wei3872452326 小时前
java笔记02
java·开发语言·笔记