Introducción: Por qué Go y las bases de datos son la pareja ideal
El lenguaje de programación Go (Golang) ha ganado popularidad gracias a su alto rendimiento, soporte integrado para concurrencia y facilidad de implementación. Sin embargo, la verdadera fortaleza de Go se revela al trabajar con bases de datos. Ya sea la relacional PostgreSQL o la orientada a documentos MongoDB, Go proporciona herramientas elegantes para una interacción eficiente con los datos.
En este artículo, analizaremos los aspectos prácticos de la conexión, la ejecución de operaciones CRUD y la optimización de consultas para PostgreSQL y MongoDB en Go. Aprenderá a utilizar paquetes estándar y controladores populares para escribir código confiable y rápido.
1. Trabajo con PostgreSQL en Go
Para trabajar con PostgreSQL en Go se utiliza el paquete estándar database/sql junto con el controlador pgx o lib/pq. Se recomienda pgx por su mejor rendimiento y soporte de funcionalidades avanzadas de PostgreSQL.
1.1. Instalación y conexión
Instale el controlador a través de go modules:
go get github.com/jackc/pgx/v5Ejemplo de conexión a la base de datos:
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("Unable to connect to database:", err) } defer pool.Close()
fmt.Println("Connected to PostgreSQL!")}Consejo: Utilice un pool de conexiones (pgxpool) para entornos de producción; esto reduce la sobrecarga de establecer nuevas conexiones.
1.2. Operaciones CRUD
Veamos las operaciones básicas con el ejemplo de la tabla users:
// CREATEfunc 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}
// READfunc 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}
// UPDATEfunc 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}
// DELETEfunc deleteUser(pool *pgxpool.Pool, id int) error { _, err := pool.Exec(context.Background(), "DELETE FROM users WHERE id = $1", id) return err}Observe el uso de consultas parametrizadas con $1, $2; esto protege contra inyecciones SQL.
1.3. Transacciones
PostgreSQL admite transacciones, lo cual es fundamental para la integridad de los datos:
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()) // reversión en caso de error
_, 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. Trabajo con MongoDB en Go
MongoDB es un documento