Jaki jest zalecany sposób łączenia się z MySQL z poziomu Go?

163

Szukam niezawodnego rozwiązania do łączenia się z bazą danych MySQL z Go. Widziałem kilka bibliotek w pobliżu, ale trudno jest określić różne stany kompletności i bieżącej konserwacji. Nie mam skomplikowanych potrzeb, ale chciałbym wiedzieć, na czym ludzie polegają lub jakie jest najbardziej standardowe rozwiązanie do łączenia się z MySQL.

Sergi Mansilla
źródło

Odpowiedzi:

263

Dostępnych jest kilka sterowników, ale należy rozważyć tylko te, które implementują interfejs API bazy danych / sql jako

  • zapewnia czystą i wydajną składnię,
  • zapewnia, że ​​możesz później zmienić sterownik bez zmiany kodu, z wyjątkiem importu i połączenia.

Dla MySQL dostępne są dwa szybkie i niezawodne sterowniki:

Użyłem ich obu w produkcji, programy działają od miesięcy z numerami połączeń w milionach bez awarii.

Inne sterowniki baz danych SQL są wymienione na go-wiki .

Importuj podczas korzystania z MyMySQL:

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

Importuj przy użyciu sterownika Go-MySQL:

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

Łączenie i zamykanie za pomocą 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

Łączenie i zamykanie za pomocą sterownika Go-MySQL:

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

Wybierz jeden wiersz:

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)

Wybierz wiele wierszy i utwórz tablicę z wynikami:

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})
}

Wstaw:

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

Przekonasz się, że praca w Go z MySQL to wspaniałe doświadczenie: nigdy nie miałem problemu, moje serwery działają przez miesiące bez błędów i wycieków. Fakt, że większość funkcji po prostu przyjmuje zmienną liczbę argumentów, ułatwia zadanie, które jest żmudne w wielu językach.

Zwróć uwagę, że jeśli w przyszłości będziesz musiał użyć innego sterownika MySQL, będziesz musiał po prostu zmienić dwie linie w jednym pliku go: linię wykonującą import i linię otwierającą połączenie.

Denys Séguret
źródło
2
Dziękuję bardzo, spróbuję. Uwielbiam to, że Go udostępnia pakiet bazy danych / sql, który mogą implementować biblioteki.
Sergi Mansilla
9
Doskonały podkład dla początkujących. Dzięki.
Rick-777
5
Lista przetestowanych sterowników (także dla innych DBMS) jest dostępna pod adresem code.google.com/p/go-wiki/wiki/SQLDrivers. Drugi popularny sterownik MySQL: github.com/Go-SQL-Driver/MySQL (napisane przeze mnie)
Julien Schmidt
1
@JulienSchmidt Zmieniłem odpowiedź, aby odnieść się do Twojego linku. Jeśli masz link do porównania między tymi dwoma sterownikami, byłoby to mile widziane.
Denys Séguret
1
@Zeynel To tylko przykład (zaczerpnięty z tego osobistego projektu ). Edytowałem, zastępując go SomeThing. Celem tego wiersza jest pokazanie, jak bezpośrednio wypełnić strukturę wynikiem zapytania bez zmiennych pośrednich.
Denys Séguret,
2

kilka rzeczy, na które należy zwrócić uwagę w przykładzie zaznaczenia 1 wiersza:

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()w tym przykładzie brakuje . musi wywołać, row.Next()aby pobrać pierwszy zwrócony wiersz.

istnieje również pewna nieelastyczność w bibliotece, która w jakiś sposób stara się promować minimalizm danych. jeśli spróbujesz wybrać kolumny inne niż Skanuj, spowoduje to wyświetlenie błędów (nie tylko ostrzeżeń)

Badoet
źródło
2
To nie jest dokładne: funkcja QueryRow zwraca * Row. Ta funkcja zapewnia, że ​​zapytanie zwraca pojedynczy wiersz. Query () zwraca (* Rows, error), co wymaga wywołania rows.Next ().
Alan LaMielle