Was ist die empfohlene Methode, um von Go aus eine Verbindung zu MySQL herzustellen?

163

Ich suche nach einer zuverlässigen Lösung, um von Go aus eine Verbindung zu einer MySQL-Datenbank herzustellen. Ich habe einige Bibliotheken gesehen, aber es ist schwierig, die verschiedenen Vollständigkeitszustände und die aktuelle Wartung zu bestimmen. Ich habe keine komplizierten Anforderungen, aber ich möchte wissen, worauf sich die Leute verlassen oder was die Standardlösung für die Verbindung mit MySQL ist.

Sergi Mansilla
quelle

Antworten:

262

Es sind einige Treiber verfügbar, aber Sie sollten nur diejenigen berücksichtigen, die die Datenbank- / SQL- API als implementieren

  • es bietet eine saubere und effiziente Syntax,
  • Es stellt sicher, dass Sie den Treiber später ändern können, ohne Ihren Code zu ändern, abgesehen von Import und Verbindung.

Für MySQL stehen zwei schnelle und zuverlässige Treiber zur Verfügung:

Ich habe beide in der Produktion verwendet, Programme laufen seit Monaten mit Verbindungsnummern in Millionenhöhe ohne Fehler.

Andere SQL-Datenbanktreiber sind im Go-Wiki aufgeführt .

Importieren bei Verwendung von MyMySQL:

import (
    "database/sql"
    _ "github.com/ziutek/mymysql/godrv"
)

Import mit Go-MySQL-Treiber:

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

Verbinden und Schließen mit MyMySQL:

con, err := sql.Open("mymysql", database+"/"+user+"/"+password)
defer con.Close()
// here you can use the connection, it will be closed when function returns

Verbinden und Schließen mit dem Go-MySQL-Treiber:

con, err := sql.Open("mysql", store.user+":"+store.password+"@/"+store.database)
defer con.Close()

Wählen Sie eine Zeile aus:

row := con.QueryRow("select mdpr, x, y, z from sometable where id=?", id)
cb := new(SomeThing)
err := row.Scan(&cb.Mdpr, &cb.X, &cb.Y, &cb.Z)

Wählen Sie mehrere Zeilen aus und erstellen Sie ein Array mit Ergebnissen:

rows, err := con.Query("select a, b from item where p1=? and p2=?", p1, p2)
if err != nil { /* error handling */}
items := make([]*SomeStruct, 0, 10)
var ida, idb uint
for rows.Next() {
    err = rows.Scan(&ida, &idb)
    if err != nil { /* error handling */}
    items = append(items, &SomeStruct{ida, idb})
}

Einfügen:

_, err = con.Exec("insert into tbl (id, mdpr, isok) values (?, ?, 1)", id, mdpr)

Sie werden sehen, dass die Arbeit in Go mit MySQL eine wunderbare Erfahrung ist: Ich hatte nie ein Problem, meine Server laufen monatelang ohne Fehler oder Undichtigkeiten. Die Tatsache, dass die meisten Funktionen einfach eine variable Anzahl von Argumenten annehmen, erleichtert eine Aufgabe, die in vielen Sprachen mühsam ist.

Beachten Sie, dass Sie, wenn Sie in Zukunft einen anderen MySQL-Treiber verwenden müssen, nur zwei Zeilen in einer Go-Datei ändern müssen: die Zeile, die den Import ausführt, und die Zeile, die die Verbindung öffnet.

Denys Séguret
quelle
2
Vielen Dank, ich werde es versuchen. Ich finde es toll, dass Go das Datenbank- / SQL-Paket bereitstellt, das Bibliotheken implementieren können.
Sergi Mansilla
9
Hervorragende Grundierung für Neulinge. Vielen Dank.
Rick-777
5
Eine Liste der getesteten Treiber (auch für andere DBMS) finden Sie unter code.google.com/p/go-wiki/wiki/SQLDrivers. Es gibt einen zweiten beliebten MySQL-Treiber: github.com/Go-SQL-Driver/MySQL (geschrieben von mir)
Julien Schmidt
1
@ JulienSchmidt Ich habe meine Antwort bearbeitet, um auf Ihren Link zu verweisen. Wenn Sie zufällig einen Link zu einem Vergleich zwischen diesen beiden Treibern haben, wäre dies willkommen.
Denys Séguret
1
@Zeynel Es ist nur ein Beispiel (aus diesem persönlichen Projekt ). Ich habe es durch ersetzt SomeThing. Der Punkt dieser Zeile soll zeigen, wie eine Struktur ohne Zwischenvariablen direkt mit dem Ergebnis Ihrer Abfrage gefüllt wird.
Denys Séguret
2

Einige Dinge, die Sie im Beispiel einer ausgewählten Zeile beachten sollten:

row := con.QueryRow("select mdpr, x, y, z from sometable where id=?",id) 
cb := new(SomeThing) 
err := row.Scan(&cb.Mdpr, &cb.X, &cb.Y, &cb.Z)

row.Next()In diesem Beispiel fehlt ein. Es muss aufgerufen werden row.Next(), um die erste zurückgegebene Zeile abzurufen.

Es gibt auch eine gewisse Inflexibilität in der Bibliothek, die auf irgendeine Weise versucht, den Datenminimalismus zu fördern. Wenn Sie versuchen, Spalten auszuwählen, die nicht gescannt sind, werden Fehler ausgegeben (nicht nur Warnungen).

Badoet
quelle
2
Dies ist nicht korrekt: Die QueryRow-Funktion gibt * Row zurück. Diese Funktion bestätigt, dass die Abfrage eine einzelne Zeile zurückgibt. Query () gibt (* Zeilen, Fehler) zurück, was einen Aufruf von rows.Next () erfordert.
Alan LaMielle