将数据库集成到Go Web应用程序的最佳方法

时间:2015-05-19 20:50:01

标签: mysql web-applications go

我刚开始在Go中开发Web应用程序。 我正在寻找将MySQL数据库集成到我的Web应用程序中的最佳方法。

我在考虑做这样的事情:

type Context struct {
     Database *sql.DB 
}
// Some database methods like Close() and Query() for Context struct here

在我的Web应用程序的主要功能中,我会有这样的事情:

db := sql.Open(...)
ctx := Context{db}

然后我会传递然后将我的Context结构传递给需要数据库连接的各种处理程序。这是一个很好的设计决策,还是有更好的方法将SQL数据库集成到我的Web应用程序中?

1 个答案:

答案 0 :(得分:1)

我通常做这样的事情:

package main

func main(){
    db,err := sql.Open(...)
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()
    http.HandleFunc("/feed", server.FeedHandler(db))
    http.HandleFunc("/gui", server.GuiHandler(db))
    ...
    log.Fatal(http.ListenAndServe(":8000", nil))
}

其中server是一个单独的包,我在其中定义,实现和测试我的所有http处理程序。

这基本上是你想到的,但是跳过了将db包装在一个不必要的结构中的步骤。我会建议将db作为全局变量。拥有全局依赖性将完全破坏以可靠的方式测试http处理程序的任何可能性。

依赖注入数据库,如上例所示,每次调用函数时都要花费两个额外的字符来输入,但它允许您使用go-sqlmock package轻松测试您的http处理程序,您肯定想要这样做随着您的网络应用程序的增长。

package server

func TestFeedHandler(t *testing.T){
    mockdb, err := sqlmock.New()
    if err != nil {
        t.Errorf("An error '%s' was not expected when opening a stub database connection", err)
    }

    columns := []string{"id", "name"}
    sqlmock.ExpectQuery("SELECT id,name from persons;").
        WillReturnRows(sqlmock.NewRows(columns).
        AddRow(1234, "bob")

   handler := FeedHandler(mockdb)

   // test that handler returns expected result

}