温馨提示×

Golang在Debian上的数据库操作指南

小樊
47
2025-11-23 09:48:04
栏目: 编程语言

在 Debian 上使用 Go 进行数据库操作

一 环境准备

  • 安装 Go(Debian 官方仓库或官网包均可):
    • 仓库安装:sudo apt update && sudo apt install golang-go
    • 官网安装示例:下载 go1.18.linux-amd64.tar.gz,解压至 /usr/local 并加入 PATH:export PATH=$PATH:/usr/local/go/bin
  • 启用 Go Modules(推荐):在项目根目录使用 go mod init <module-name>,依赖通过 go get 管理,无需手动设置 GOPATH/GOROOT

二 安装数据库与驱动

  • 安装数据库服务器(以 MySQL 为例):
    • 安装与启动:sudo apt install mysql-server
    • 安全初始化:sudo mysql_secure_installation
    • 创建应用专用账户与库(示例):
      • CREATE DATABASE mydb;
      • CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';
      • GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost';
      • FLUSH PRIVILEGES;
  • 安装 Go 驱动(按所用数据库选择其一或多种):
    • 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
    • MongoDB(NoSQL):go get -u go.mongodb.org/mongo-driver/mongo

三 连接与 CRUD 示例

  • MySQL 最小可用示例(使用占位符与连接参数)
    • 安装驱动:go get -u github.com/go-sql-driver/mysql
    • 代码示例(注意 DSN 参数:charset=utf8mb4&parseTime=True&loc=Local):
      package main
      
      import (
          "database/sql"
          "fmt"
          _ "github.com/go-sql-driver/mysql"
      )
      
      func main() {
          dsn := "myuser:mypassword@tcp(localhost:3306)/mydb?charset=utf8mb4&parseTime=True&loc=Local"
          db, err := sql.Open("mysql", dsn)
          if err != nil { panic(err) }
          defer db.Close()
      
          if err = db.Ping(); err != nil { panic(err) }
          fmt.Println("Connected to MySQL")
      
          // Create
          _, err = db.Exec("INSERT INTO users(name, age) VALUES (?, ?)", "Alice", 30)
          if err != nil { panic(err) }
      
          // Read
          var id int
          var name string
          var age int
          err = db.QueryRow("SELECT id, name, age FROM users WHERE name = ?", "Alice").Scan(&id, &name, &age)
          if err != nil { panic(err) }
          fmt.Printf("User: %d, %s, %d\n", id, name, age)
      
          // Update
          _, err = db.Exec("UPDATE users SET age = ? WHERE name = ?", 31, "Alice")
          if err != nil { panic(err) }
      
          // Delete
          _, err = db.Exec("DELETE FROM users WHERE name = ?", "Alice")
          if err != nil { panic(err) }
      }
      
  • PostgreSQL 最小可用示例(使用 $1/$2 占位符)
    • 安装驱动:go get -u github.com/lib/pq
    • 代码示例(开发环境可用 sslmode=disable,生产请启用 SSL):
      package main
      
      import (
          "database/sql"
          "log"
          _ "github.com/lib/pq"
      )
      
      func main() {
          connStr := "user=myuser dbname=mydb password=mypassword host=localhost sslmode=disable"
          db, err := sql.Open("postgres", connStr)
          if err != nil { log.Fatal(err) }
          defer db.Close()
      
          if err = db.Ping(); err != nil { log.Fatal(err) }
          log.Println("Connected to PostgreSQL")
      
          var id int
          err = db.QueryRow("INSERT INTO users(name, email) VALUES ($1, $2) RETURNING id",
              "Bob", "bob@example.com").Scan(&id)
          if err != nil { log.Fatal(err) }
          log.Printf("New record ID: %d\n", id)
      }
      
  • 运行程序:go run main.go

四 连接池与最佳实践

  • 连接池配置(提升并发与稳定性):
    db.SetMaxOpenConns(25)
    db.SetMaxIdleConns(5)
    db.SetConnMaxLifetime(5 * time.Minute)
    
  • 预编译语句与参数化查询(防止 SQL 注入):
    stmt, err := db.Prepare("SELECT id, name FROM users WHERE name = $1")
    defer stmt.Close()
    var id int
    var name string
    err = stmt.QueryRow("John").Scan(&id, &name)
    
  • 错误处理与日志:对 db.Ping()QueryRow()Exec() 等返回值严格判错,使用结构化日志记录上下文信息。
  • 配置管理:避免硬编码凭据,优先使用环境变量或配置文件(如 .env、Vault 等)。

五 常见问题与排查

  • 驱动未注册或导入错误:PostgreSQL 需空导入驱动 _ "github.com/lib/pq";MySQL 需 _ "github.com/go-sql-driver/mysql",否则会出现未知驱动错误。
  • DSN/连接参数错误:
    • MySQL 建议使用 charset=utf8mb4&parseTime=True&loc=Local,避免中文乱码与时区问题。
    • PostgreSQL 开发环境可用 sslmode=disable,生产环境请配置为 require/verify-full 并准备证书。
  • 权限与网络:
    • 确保数据库用户允许从应用主机连接(如 GRANT ... TO 'myuser'@'localhost';远程需配置 'myuser'@'%' 与防火墙/监听地址)。
    • 本机测试可用 localhost,容器/远程请使用服务器 IP/域名 与开放端口。
  • 资源与连接泄漏:
    • *sql.Rows 务必 defer rows.Close(),并在循环后检查 rows.Err()
    • 复用全局 *sql.DB,不要频繁 sql.Open;按需配置连接池参数。

0