Golang数据库操作大全

最近在学习Golang操作数据库,想请教几个问题:1) Golang中常用的数据库驱动有哪些推荐?2) 使用database/sql包时如何处理连接池和长连接?3) 如何实现事务操作和错误回滚?4) ORM框架如GORM和XORM在实际项目中如何选择?5) 有没有处理SQL注入的最佳实践?希望能得到一些实际案例的分享。

2 回复

推荐使用database/sql标准库,配合驱动如pq(PostgreSQL)或go-sqlite3。常用操作包括:

  1. 连接数据库:sql.Open()
  2. 查询:Query/QueryRow
  3. 插入/更新:Exec
  4. 事务:Begin/Commit/Rollback
  5. 预处理:Prepare 建议搭配ORM库如GORM简化操作。注意连接池和错误处理。

更多关于Golang数据库操作大全的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang数据库操作指南

1. 数据库连接

MySQL连接示例

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    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())
    }
}

PostgreSQL连接

import (
    "database/sql"
    _ "github.com/lib/pq"
)

db, err := sql.Open("postgres", "host=localhost port=5432 user=user password=password dbname=dbname sslmode=disable")

2. 基本CRUD操作

查询数据

// 单行查询
var id int
var name string
err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", 1).Scan(&id, &name)

// 多行查询
rows, err := db.Query("SELECT id, name FROM users WHERE age > ?", 18)
defer rows.Close()

for rows.Next() {
    var id int
    var name string
    err = rows.Scan(&id, &name)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(id, name)
}

插入数据

result, err := db.Exec("INSERT INTO users (name, email) VALUES (?, ?)", "John", "john@example.com")
if err != nil {
    log.Fatal(err)
}

lastInsertID, err := result.LastInsertId()
rowsAffected, err := result.RowsAffected()

更新数据

result, err := db.Exec("UPDATE users SET name = ? WHERE id = ?", "Jane", 1)

删除数据

result, err := db.Exec("DELETE FROM users WHERE id = ?", 1)

3. 事务处理

tx, err := db.Begin()
if err != nil {
    log.Fatal(err)
}

// 执行多个操作
_, err = tx.Exec("UPDATE accounts SET balance = balance - ? WHERE id = ?", 100, 1)
if err != nil {
    tx.Rollback()
    return
}

_, err = tx.Exec("UPDATE accounts SET balance = balance + ? WHERE id = ?", 100, 2)
if err != nil {
    tx.Rollback()
    return
}

err = tx.Commit()
if err != nil {
    log.Fatal(err)
}

4. 预处理语句

stmt, err := db.Prepare("INSERT INTO users (name, email) VALUES (?, ?)")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

for i := 0; i < 10; i++ {
    _, err = stmt.Exec(fmt.Sprintf("User%d", i), fmt.Sprintf("user%d@example.com", i))
}

5. 使用ORM(GORM)

安装GORM

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql

基本用法

import (
    "gorm.io/gorm"
    "gorm.io/driver/mysql"
)

type User struct {
    gorm.Model
    Name  string
    Email string `gorm:"uniqueIndex"`
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    
    // 自动迁移
    db.AutoMigrate(&User{})
    
    // 创建记录
    user := User{Name: "John", Email: "john@example.com"}
    db.Create(&user)
    
    // 查询
    var result User
    db.First(&result, 1)
    db.Where("name = ?", "John").First(&result)
    
    // 更新
    db.Model(&user).Update("Name", "Jane")
    
    // 删除
    db.Delete(&user)
}

6. 连接池配置

db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)

最佳实践

  1. 及时关闭连接和结果集
  2. 使用预处理语句防止SQL注入
  3. 合理配置连接池参数
  4. 使用事务保证数据一致性
  5. 处理所有可能的错误

这个指南涵盖了Golang数据库操作的主要方面,从基本的SQL操作到使用ORM框架,帮助你高效地进行数据库开发。

回到顶部