Introducción: Por qué Go y las bases de datos son la pareja ideal
\nGo (Golang) es un lenguaje compilado moderno creado por Google. Sus principales ventajas son el alto rendimiento, la simplicidad y el soporte integrado para la concurrencia. Cuando se trata de trabajar con bases de datos, Go ofrece potentes bibliotecas estándar y controladores de terceros populares para cualquier DBMS.
\nEn este artículo, analizaremos cómo conectarse y realizar operaciones básicas con las dos bases de datos más populares: la relacional PostgreSQL y la orientada a documentos MongoDB. El material está dirigido a desarrolladores principiantes que ya están familiarizados con los conceptos básicos de la sintaxis de Go.
\n\n1. Preparación del entorno e instalación de controladores
\nAntes de escribir código, asegúrese de tener Go instalado (versión 1.21+). Para trabajar con bases de datos, necesitaremos controladores. Instálelos usando los comandos:
\ngo get github.com/lib/pq // para PostgreSQL\ngo get go.mongodb.org/mongo-driver // para MongoDB\nAsegúrese también de que los servidores de bases de datos correspondientes estén ejecutándose en su máquina (localmente o mediante Docker).
\n\n1.1. Estructura del proyecto
\nCree un archivo main.go. Toda la lógica se concentrará en él por simplicidad. En proyectos reales, se debe dividir el código en paquetes.
2. Trabajo con PostgreSQL en Go
\nPostgreSQL es un potente DBMS relacional. Para trabajar con él en Go, usamos el paquete database/sql y el controlador lib/pq.
2.1. Conexión a la base de datos
\nCreemos una función de conexión. La cadena de conexión (DSN) contiene el host, puerto, nombre de usuario y base de datos.
\npackage main\n\nimport (\n "database/sql"\n "fmt"\n "log"\n\n _ "github.com/lib/pq"\n)\n\nfunc main() {\n connStr := "host=localhost port=5432 user=postgres password=secret dbname=testdb sslmode=disable"\n db, err := sql.Open("postgres", connStr)\n if err != nil {\n log.Fatal("Error de conexión:", err)\n }\n defer db.Close()\n\n // Verificamos la conexión\n err = db.Ping()\n if err != nil {\n log.Fatal("No se pudo establecer la conexión:", err)\n }\n fmt.Println("¡Conectado exitosamente a PostgreSQL!")\n}\nImportante: sql.Open no crea una conexión real, solo un pool. La conexión real ocurre en la primera consulta o al llamar a Ping().
2.2. Creación de tabla e inserción de datos
\nAhora creemos la tabla users y agreguemos algunos registros.
// Creación de tabla\ncreateTable := `\nCREATE TABLE IF NOT EXISTS users (\n id SERIAL PRIMARY KEY,\n name VARCHAR(100) NOT NULL,\n email VARCHAR(100) UNIQUE NOT NULL,\n age INT\n);`\n_, err = db.Exec(createTable)\nif err != nil {\n log.Fatal("Error al crear la tabla:", err)\n}\n\n// Inserción de datos\ninsert := `INSERT INTO users (name, email, age) VALUES ($1, $2, $3)`\n_, err = db.Exec(insert, "Iván Petrov", "ivan@example.com", 30)\nif err != nil {\n log.Fatal("Error al insertar:", err)\n}\nfmt.Println("Datos agregados")\nObserve el uso de los marcadores de posición $1, $2 — esto es protección contra inyecciones SQL.
2.3. Lectura y actualización de datos
\nRealicemos una consulta de selección y actualicemos la edad del usuario.
\n// Lectura de datos\nrows, err := db.Query("SELECT id, name, email, age FROM users")\nif err != nil {\n log.Fatal(err)\n}\ndefer rows.Close()\n\nfor rows.Next() {\n var id int\n var name, email string\n var age int\n err := rows.Scan(&id, &name, &email, &age)\n if err != nil {\n log.Fatal(err)\n }\n fmt.Printf("ID: %d, Nombre: %s, Email: %s, Edad: %d\\n", id, name, email, age)\n}\n\n// Actualización\n_, err = db.Exec("UPDATE users SET age = $1 WHERE name = $2", 31, "Iván Petrov")\nif err != nil {\n log.Fatal(err)\n}\nfmt.Println("Edad actualizada")\n\n