Arbeit mit Datenbanken in Go: PostgreSQL und MongoDB
Go (Golang) ist eine moderne, kompilierte Sprache, die sich ideal für die Erstellung hochbelastbarer Backend-Dienste eignet. Eine der Hauptaufgaben jedes Backends ist die Arbeit mit Datenbanken. In diesem Artikel werden wir im Detail besprechen, wie man eine Verbindung herstellt und CRUD-Operationen mit den beiden beliebtesten DBMS durchführt: der relationalen PostgreSQL und der dokumentenorientierten MongoDB. Sie erhalten fertige Codebeispiele, Best Practices und Tipps zur Abfrageoptimierung.
1. Vorbereitung der Umgebung und Installation der Treiber
Stellen Sie vor Beginn sicher, dass Go Version 1.19 oder höher installiert ist. Für die Arbeit mit Datenbanken benötigen wir zwei Hauptpakete:
- database/sql — das Standard-Go-Paket für die Arbeit mit SQL-Datenbanken (allgemeine Schnittstelle);
- lib/pq — der Treiber für PostgreSQL;
- go.mongodb.org/mongo-driver — der offizielle MongoDB-Treiber.
Installation der Treiber über go get:
go get github.com/lib/pqgo get go.mongodb.org/mongo-driver/mongoErstellen Sie ein neues Modul für Ihr Projekt:
mkdir go-db-examplecd go-db-examplego mod init go-db-example2. Arbeiten mit PostgreSQL in Go
PostgreSQL ist ein leistungsstarkes objektrelationales DBMS. In Go erfolgt die Arbeit damit über die Schnittstelle database/sql.
2.1 Verbindung zur Datenbank
Erstellen wir eine Datei main.go und schreiben die Verbindung zu einer lokalen Postgres-Datenbank:
package main
import ( "database/sql" "fmt" "log"
_ "github.com/lib/pq")
func main() { // Verbindungszeichenfolge: user password dbname sslmode connStr := "user=postgres password=mysecretpassword dbname=testdb sslmode=disable" db, err := sql.Open("postgres", connStr) if err != nil { log.Fatal("Verbindungsfehler:", err) } defer db.Close()
// Verbindung prüfen err = db.Ping() if err != nil { log.Fatal("Verbindung zur DB fehlgeschlagen:", err) } fmt.Println("Erfolgreich mit PostgreSQL verbunden!")}2.2 Tabelle erstellen und Daten einfügen
Nach der Verbindung erstellen wir eine Tabelle users und fügen einige Datensätze ein:
// Tabelle erstellencreateTable := `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("Fehler beim Erstellen der Tabelle:", err)}
// Daten einfügeninsert := `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("Einfügefehler:", err)}fmt.Println("Daten hinzugefügt")2.3 Daten lesen (SELECT)
Verwenden Sie QueryRow für einen einzelnen Datensatz und Query für mehrere:
// Einzelnen Datensatz abrufenvar 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("Scan-Fehler:", err)}fmt.Printf("ID: %d, Name: %s, Email: %s, Alter: %v", id, name, email, age)
// Alle Datensätze abrufenrows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")if err != nil { log.Fatal("Abfragefehler:", err)}defer rows.Close()
for rows.Next() { err := rows.Scan(&id, &name, &email) if err != nil { log.Fatal("Fehler beim Lesen der Zeile:", err) } fmt.Printf("User: %d | %s | %s", id, name, email)}Wichtig: Behandeln Sie immer sql.NullInt64 für nullable-Felder, um Panik bei NULL-Werten zu vermeiden.