Golang SQL编程指南
最近在学习Golang操作数据库,想请教下大家:在使用database/sql包时有哪些需要注意的性能优化点?比如连接池配置、预处理语句使用等方面。另外对于复杂查询的场景,有没有推荐的ORM框架或者更高效的查询方案?
2 回复
推荐使用database/sql包和驱动(如pq、go-sqlite3)。建议使用预处理语句防注入,结合context控制超时。推荐使用sqlx简化数据映射。注意连接池配置和错误处理。
更多关于Golang SQL编程指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang SQL编程指南
Go语言提供了database/sql包来操作SQL数据库,这是一个通用接口,需要配合特定数据库驱动使用。
1. 安装数据库驱动
// MySQL驱动
go get -u github.com/go-sql-driver/mysql
// PostgreSQL驱动
go get -u github.com/lib/pq
// SQLite驱动
go get -u github.com/mattn/go-sqlite3
2. 连接数据库
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
// MySQL连接示例
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
panic(err.Error())
}
defer db.Close()
// 验证连接
err = db.Ping()
if err != nil {
panic(err.Error())
}
}
3. 基本CRUD操作
查询数据
type User struct {
ID int
Name string
Age int
}
// 单行查询
func getUser(db *sql.DB, id int) (*User, error) {
var user User
err := db.QueryRow("SELECT id, name, age FROM users WHERE id = ?", id).
Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
return nil, err
}
return &user, nil
}
// 多行查询
func getUsers(db *sql.DB) ([]User, error) {
rows, err := db.Query("SELECT id, name, age FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
err := rows.Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
插入数据
func insertUser(db *sql.DB, name string, age int) (int64, error) {
result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", name, age)
if err != nil {
return 0, err
}
return result.LastInsertId()
}
更新数据
func updateUser(db *sql.DB, id int, name string, age int) error {
_, err := db.Exec("UPDATE users SET name = ?, age = ? WHERE id = ?", name, age, id)
return err
}
删除数据
func deleteUser(db *sql.DB, id int) error {
_, err := db.Exec("DELETE FROM users WHERE id = ?", id)
return err
}
4. 事务处理
func transferMoney(db *sql.DB, fromID, toID int, amount float64) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p)
} else if err != nil {
tx.Rollback()
} else {
err = tx.Commit()
}
}()
// 扣款
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", amount, fromID)
if err != nil {
return err
}
// 存款
_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", amount, toID)
return err
}
5. 预处理语句
func batchInsertUsers(db *sql.DB, users []User) error {
stmt, err := db.Prepare("INSERT INTO users (name, age) VALUES (?, ?)")
if err != nil {
return err
}
defer stmt.Close()
for _, user := range users {
_, err := stmt.Exec(user.Name, user.Age)
if err != nil {
return err
}
}
return nil
}
6. 连接池配置
db.SetMaxOpenConns(25) // 最大连接数
db.SetMaxIdleConns(5) // 最大空闲连接数
db.SetConnMaxLifetime(5 * time.Minute) // 连接最大生命周期
最佳实践
- 总是检查错误并处理
- 使用
defer关闭连接和资源 - 使用预处理语句防止SQL注入
- 合理配置连接池参数
- 在事务中处理相关操作
- 使用结构体映射查询结果
这个指南涵盖了Go语言SQL编程的主要方面,帮助你安全高效地进行数据库操作。

