Travailler avec les bases de données en Go : PostgreSQL et MongoDB
Go (Golang) est un langage compilé moderne, idéal pour créer des services backend à forte charge. L'une des tâches clés de tout backend est de travailler avec des bases de données. Dans cet article, nous allons détailler comment se connecter et effectuer des opérations CRUD avec deux des SGBD les plus populaires : le relationnel PostgreSQL et l'orienté documents MongoDB. Vous obtiendrez des exemples de code prêts à l'emploi, des best practices et des conseils pour optimiser les requêtes.
1. Préparation de l'environnement et installation des drivers
Avant de commencer, assurez-vous d'avoir installé Go version 1.19 ou supérieure. Pour travailler avec les bases de données, nous aurons besoin de deux packages principaux :
- database/sql — le package standard de Go pour travailler avec les bases SQL (interface commune) ;
- lib/pq — le driver pour PostgreSQL ;
- go.mongodb.org/mongo-driver — le driver officiel MongoDB.
Installation des drivers via go get :
go get github.com/lib/pqgo get go.mongodb.org/mongo-driver/mongoCréez un nouveau module pour votre projet :
mkdir go-db-examplecd go-db-examplego mod init go-db-example2. Travailler avec PostgreSQL en Go
PostgreSQL est un SGBD objet-relationnel puissant. En Go, le travail avec lui se fait via l'interface database/sql.
2.1 Connexion à la base de données
Créons un fichier main.go et écrivons la connexion à une base de données Postgres locale :
package main
import ( "database/sql" "fmt" "log"
_ "github.com/lib/pq")
func main() { // Chaîne de connexion : user password dbname sslmode connStr := "user=postgres password=mysecretpassword dbname=testdb sslmode=disable" db, err := sql.Open("postgres", connStr) if err != nil { log.Fatal("Erreur de connexion :", err) } defer db.Close()
// Vérifions la connexion err = db.Ping() if err != nil { log.Fatal("Impossible de se connecter à la BD :", err) } fmt.Println("Connecté avec succès à PostgreSQL !")}2.2 Création d'une table et insertion de données
Après la connexion, créons une table users et insérons quelques enregistrements :
// Création de la tablecreateTable := `CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, age INT);`
_, err = db.Exec(createTable)if err != nil { log.Fatal("Erreur lors de la création de la table :", err)}
// Insertion de donnéesinsert := `INSERT INTO users (name, email, age) VALUES ($1, $2, $3)`_, err = db.Exec(insert, "Anna Petrova", "anna@example.com", 28)if err != nil { log.Fatal("Erreur d'insertion :", err)}fmt.Println("Données ajoutées")2.3 Lecture de données (SELECT)
Utilisons QueryRow pour un seul enregistrement et Query pour plusieurs :
// Récupération d'un seul enregistrementvar id intvar name, email stringvar age sql.NullInt64
row := db.QueryRow("SELECT id, name, email, age FROM users WHERE email = $1", "anna@example.com")err = row.Scan(&id, &name, &email, &age)if err != nil { log.Fatal("Erreur de scan :", err)}fmt.Printf("ID : %d, Nom : %s, Email : %s, Âge : %v", id, name, email, age)
// Récupération de tous les enregistrementsrows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")if err != nil { log.Fatal("Erreur de requête :", err)}defer rows.Close()
for rows.Next() { err := rows.Scan(&id, &name, &email) if err != nil { log.Fatal("Erreur de lecture de la ligne :", err) } fmt.Printf("User : %d | %s | %s", id, name, email)}Important : Traitez toujours sql.NullInt64 pour les champs nullable afin d'éviter une panique en cas de valeurs NULL.