2013-06-29 42 views
34

我是围棋菜鸟,无法找到打开围棋一个MySQL连接,然后处理HTTP之间共享它的任何一个完整的例子。这是我的代码到目前为止,我将如何使用我在HomeHandler中的main()中打开的数据库连接?如何在http goroutines之间共享mysql连接?

package main 

import (
    "database/sql" 
    "fmt" 
    _ "github.com/go-sql-driver/mysql" 
    "github.com/gorilla/mux" 
    "log" 
    "net/http" 
) 

func main() { 

    fmt.Println("starting up") 

    db, err := sql.Open("mysql", "root:@/mydb?charset=utf8") 
    if err != nil { 
    log.Fatalf("Error opening database: %v", err) 
    } 

    db.SetMaxIdleConns(100) 

    r := mux.NewRouter() 
    r.HandleFunc("/", HomeHandler) 

    http.Handle("/", r) 
    http.ListenAndServe(":8080", nil) 

} 

func HomeHandler(w http.ResponseWriter, r *http.Request) { 

    fmt.Fprintf(w, "home") 

} 

回答

55

数据库/ sql包为您自动管理连接池。

sql.Open(..)返回一个句柄,其中表示连接池,而不是单个连接。如果池中的所有连接都忙碌,那么数据库/ sql包会自动打开一个新连接。

应用到你的代码,这意味着,你只需要共享的DB-手柄,并在HTTP处理程序使用它:

package main 

import (
    "database/sql" 
    "fmt" 
    "github.com/gorilla/mux" 
    _ "github.com/go-sql-driver/mysql" 
    "log" 
    "net/http" 
) 

var db *sql.DB // global variable to share it between main and the HTTP handler 

func main() { 
    fmt.Println("starting up") 

    var err error 
    db, err = sql.Open("mysql", "[email protected](/tmp/mysql.sock)/mydb") // this does not really open a new connection 
    if err != nil { 
     log.Fatalf("Error on initializing database connection: %s", err.Error()) 
    } 

    db.SetMaxIdleConns(100) 

    err = db.Ping() // This DOES open a connection if necessary. This makes sure the database is accessible 
    if err != nil { 
     log.Fatalf("Error on opening database connection: %s", err.Error()) 
    } 

    r := mux.NewRouter() 
    r.HandleFunc("/", HomeHandler) 

    http.Handle("/", r) 
    http.ListenAndServe(":8080", nil) 
} 

func HomeHandler(w http.ResponseWriter, r *http.Request) { 
    var msg string 
    err := db.QueryRow("SELECT msg FROM hello WHERE page=?", "home").Scan(&msg) 
    if err != nil { 
     fmt.Fprintf(w, "Database Error!") 
    } else { 
     fmt.Fprintf(w, msg) 
    } 
} 
+0

嗨朱利安,谢谢回答。不能期待比Go-MySQL-Driver的作者更好的源代码!这似乎有可能是代码中的一个错字,我得到一个编译错误:'./main.go:18:不能指定* sql.DB以分贝(类型sql.DB)在多个assignment' – Jason

+0

对不起,我固定现在键入。 @ fmt.Println.MKO,这不起作用仍然是不正确的。数据库/ sql的设计完全适用于像这样的并发用例。 –

+0

仅供参考,这里有几个简单的例子,如何访问数据库中的HTTP处理程序: https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/go/src/hello/hello.go –

相关问题