从Go连接到MySQL的推荐方法是什么?


163

我正在寻找一种可靠的解决方案,以从Go连接到MySQL数据库。我已经看到了一些库,但是很难确定完整性和当前维护的不同状态。我没有复杂的需求,但是我想知道人们所依赖的是什么,或者连接到MySQL的最标准的解决方案是什么。

Answers:


262

有一些驱动程序可用,但您应该仅考虑将实现数据库/ sql API的那些驱动程序视为

  • 它提供了一种干净高效的语法,
  • 它确保您以后可以更改驱动程序而无需更改代码(导入和连接除外)。

两个快速可靠的驱动程序可用于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驱动程序,则只需要在一个go文件中更改两行:执行导入的行和打开连接的行。


2
非常感谢,我会尝试的。我喜欢Go提供了库可以实现的数据库/ sql包。
Sergi Mansilla 2012年

9
优秀的新手入门。谢谢。
Rick-777

5
可通过code.google.com/p/go-wiki/wiki/SQLDrivers获得经过测试的驱动程序列表(也适用于其他DBMS)。 还有第二种流行的MySQL驱动程序:github.com/Go-SQL-Driver/MySQL(由我撰写)
Julien Schmidt

1
@JulienSchmidt我编辑了答案以引用您的链接。如果您碰巧拥有这两个驱动程序之间的比较链接,那将是受欢迎的。
DenysSéguret13年

1
@Zeynel仅仅是一个示例(摘自该个人项目)。我编辑了用替换它SomeThing。该行的重点是显示如何在没有中间变量的情况下用查询结果直接填充结构。
DenysSéguret13年

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()来获取返回的第一行。

该库还存在一定的灵活性,以某种方式试图促进数据的简约性。如果您尝试选择非扫描列,则会抛出错误(不仅是警告)


2
这是不准确的:QueryRow函数返回* Row。此函数断言查询返回单行。Query()返回(*行,错误),这确实需要调用rows.Next()。
艾伦·拉米勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.