2013-06-29 95 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 –

相關問題