在 Debian 上使用 Go 进行数据库操作
一 环境准备
sudo apt update && sudo apt install golang-goexport PATH=$PATH:/usr/local/go/bingo mod init <module-name>,依赖通过 go get 管理,无需手动设置 GOPATH/GOROOT。二 安装数据库与驱动
sudo apt install mysql-serversudo mysql_secure_installationCREATE DATABASE mydb;CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword';GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost';FLUSH PRIVILEGES;go get -u github.com/go-sql-driver/mysqlgo get -u github.com/lib/pqgo get -u github.com/mattn/go-sqlite3go get -u go.mongodb.org/mongo-driver/mongo三 连接与 CRUD 示例
go get -u github.com/go-sql-driver/mysqlcharset=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) }
}
$1/$2 占位符)
go get -u github.com/lib/pqsslmode=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)
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 等)。五 常见问题与排查
_ "github.com/lib/pq";MySQL 需 _ "github.com/go-sql-driver/mysql",否则会出现未知驱动错误。charset=utf8mb4&parseTime=True&loc=Local,避免中文乱码与时区问题。sslmode=disable,生产环境请配置为 require/verify-full 并准备证书。GRANT ... TO 'myuser'@'localhost';远程需配置 'myuser'@'%' 与防火墙/监听地址)。localhost,容器/远程请使用服务器 IP/域名 与开放端口。*sql.Rows 务必 defer rows.Close(),并在循环后检查 rows.Err()。*sql.DB,不要频繁 sql.Open;按需配置连接池参数。