2013-06-29 20 views
34

私はGo noobですので、Goでmysql接続を開き、httpハンドラ間で共有する完全な例は見つかりません。これまでのコードはここまでですが、HomeHandlerのmain()でオープンしたdb接続をどうすれば使用できますか?httpゴルーチン間で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:複数の代入でdb(type sql.DB)に* sql.DBを割り当てることができません ' – Jason

+0

申し訳ありませんが、私はこの問題を修正しました。今すぐ入力してください。 @ fmt.Println.MKOこれはうまくいきません。 database/sqlは、このような同時使用のケースに対して正確に設計されています。 –

+0

FYI、HTTPハンドラでDBにアクセスする簡単な例をいくつか示します: https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/go/src/hello/hello.go –

関連する問題