引言:为什么Go与数据库是完美搭档
Go编程语言(Golang)凭借其高性能、内置并发支持以及部署简便性而广受欢迎。然而,Go的真正威力在与数据库协同工作时才得以充分展现。无论是关系型数据库PostgreSQL还是文档型数据库MongoDB,Go都提供了优雅的工具来实现高效的数据交互。
在本文中,我们将探讨在Go中连接、执行CRUD操作以及优化PostgreSQL和MongoDB查询的实际方面。您将学习如何使用标准包和流行的驱动程序来编写可靠且快速的代码。
1. 在Go中使用PostgreSQL
在Go中操作PostgreSQL,通常使用标准包database/sql配合pgx或lib/pq驱动程序。推荐使用pgx,因为它性能更优且支持PostgreSQL的高级特性。
1.1. 安装与连接
通过go modules安装驱动程序:
go get github.com/jackc/pgx/v5数据库连接示例:
package main
import ( "context" "fmt" "github.com/jackc/pgx/v5/pgxpool" "log")
func main() { dsn := "postgres://user:password@localhost:5432/mydb?sslmode=disable" pool, err := pgxpool.New(context.Background(), dsn) if err != nil { log.Fatal("无法连接到数据库:", err) } defer pool.Close()
fmt.Println("已连接到PostgreSQL!")}建议:在生产环境中使用连接池(pgxpool)——这可以减少建立新连接的开销。
1.2. CRUD操作
以users表为例,演示基本操作:
// 创建func createUser(pool *pgxpool.Pool, name string, email string) (int, error) { var id int err := pool.QueryRow(context.Background(), "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id", name, email).Scan(&id) if err != nil { return 0, err } return id, nil}
// 读取func getUser(pool *pgxpool.Pool, id int) (string, string, error) { var name, email string err := pool.QueryRow(context.Background(), "SELECT name, email FROM users WHERE id = $1", id).Scan(&name, &email) if err != nil { return "", "", err } return name, email, nil}
// 更新func updateUserEmail(pool *pgxpool.Pool, id int, newEmail string) error { _, err := pool.Exec(context.Background(), "UPDATE users SET email = $1 WHERE id = $2", newEmail, id) return err}
// 删除func deleteUser(pool *pgxpool.Pool, id int) error { _, err := pool.Exec(context.Background(), "DELETE FROM users WHERE id = $1", id) return err}请注意使用带$1、$2的参数化查询——这可以防止SQL注入攻击。
1.3. 事务
PostgreSQL支持事务,这对数据完整性至关重要:
func transferMoney(pool *pgxpool.Pool, fromID, toID int, amount float64) error { tx, err := pool.Begin(context.Background()) if err != nil { return err } defer tx.Rollback(context.Background()) // 出错时回滚
_, err = tx.Exec(context.Background(), "UPDATE accounts SET balance = balance - $1 WHERE id = $2", amount, fromID) if err != nil { return err }
_, err = tx.Exec(context.Background(), "UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, toID) if err != nil { return err }
return tx.Commit(context.Background())}2. 在Go中使用MongoDB
MongoDB是一种文档