Go语言的标准库 database/sql
提供了与 SQL 数据库交互的通用接口,但需要搭配具体的数据库驱动(如 MySQL、PostgreSQL 等)使用。以下是 database/sql
的核心方法及示例说明:
1. 连接数据库
sql.Open(driverName, dataSourceName)
连接数据库并返回 *sql.DB
对象(需先注册驱动)。
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()
验证数据库连接是否有效。
err = db.Ping()
if err != nil {panic("数据库连接失败: " + err.Error())
}
3. 执行查询
DB.Query()
执行查询语句并返回多行结果(*sql.Rows
)。
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 intvar name stringerr = 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
)。
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
。
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注入,提升性能)。
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
对象。
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)
设置最大打开连接数和最大空闲连接数。
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 注入。
- 事务操作需确保提交或回滚,避免资源泄漏。
- 必须导入具体的数据库驱动(如