Какой рекомендуемый способ подключения к MySQL из Go?

163

Я ищу надежное решение для подключения к базе данных MySQL от Go. Я видел несколько библиотек вокруг, но трудно определить различные состояния полноты и текущего обслуживания. У меня нет сложных потребностей, но я хотел бы знать, на что люди полагаются или какое самое стандартное решение для подключения к MySQL.

Sergi Mansilla
источник

Ответы:

263

Доступно несколько драйверов, но вы должны рассматривать только те, которые реализуют API базы данных / sql как

  • он обеспечивает чистый и эффективный синтаксис,
  • это гарантирует, что вы сможете позже изменить драйвер без изменения кода, кроме импорта и подключения.

Для MySQL доступны два быстрых и надежных драйвера:

Я использовал их оба в производстве, программы работают месяцами с номерами соединений в миллионах без сбоев.

Другие драйверы базы данных SQL перечислены в go-wiki .

Импорт при использовании MyMySQL:

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

Импорт при использовании Go-MySQL-Driver:

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

Подключение и закрытие с использованием 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

Подключение и закрытие с помощью Go-MySQL-Driver:

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

Выберите одну строку:

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)

Выберите несколько строк и создайте массив с результатами:

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

Вставить:

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

Вы увидите, что работа в Go с MySQL - это восхитительный опыт: у меня никогда не было проблем, мои серверы работали месяцами без ошибок или утечек. Тот факт, что большинство функций просто принимает переменное число аргументов, облегчает задачу, которая утомительна во многих языках.

Обратите внимание, что если в будущем вам понадобится другой драйвер MySQL, вам просто нужно изменить две строки в одном файле: строку, выполняющую импорт, и строку, открывающую соединение.

Денис Сегюре
источник
2
Большое спасибо, я попробую. Мне нравится, что Go предоставляет пакет database / sql, который библиотеки могут реализовать.
Sergi Mansilla
9
Отличный учебник для начинающих. Спасибо.
Рик-777
5
Список протестированных драйверов (также для других СУБД) доступен по адресу code.google.com/p/go-wiki/wiki/SQLDrivers. Существует второй популярный драйвер MySQL: github.com/Go-SQL-Driver/MySQL. (написано мной)
Жюльен Шмидт
1
@JulienSchmidt Я отредактировал свой ответ для ссылки на вашу ссылку. Если у вас есть ссылка на сравнение между этими двумя драйверами, это будет приветствоваться.
Денис Сегюре
1
@Zeynel Это всего лишь пример (взят из этого личного проекта ). Я редактировал, заменяя его на SomeThing. Смысл этой строки - показать, как напрямую заполнить структуру результатом вашего запроса без промежуточных переменных.
Денис Сегюре
2

Несколько вещей, чтобы принять к сведению пример выбора 1 строки:

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()в этом примере. это нужно вызвать, row.Next()чтобы захватить первый возвращенный ряд.

также есть некоторая негибкость к библиотеке, которая каким-то образом пытается продвигать минимализм данных. если вы попытаетесь выбрать столбцы, которые не сканируются, будут выданы ошибки (а не только предупреждения)

Badoet
источник
2
Это не точно: функция QueryRow возвращает * Row. Эта функция утверждает, что запрос возвращает одну строку. Query () возвращает (* Rows, error), что требует вызова rows.Next ().
Алан Ламьель