2013-06-29 10 views
34

Sono un go noob e non riesco a trovare alcun esempio completo di apertura di una connessione mysql in Go e quindi la condivisione tra gestori HTTP. Ecco il mio codice fino ad ora, come potrei usare la connessione db che ho aperto in main() nel mio HomeHandler?Come condividere la connessione mysql tra le goroutine http?

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") 

} 

risposta

55

Il pacchetto database/sql gestisce automaticamente il pool di connessioni.

sql.Open(..) restituisce un handle che rappresenta un pool di connessioni, non una singola connessione. Il pacchetto database/sql apre automaticamente una nuova connessione se tutte le connessioni nel pool sono occupate.

applicato al tuo codice di questo mezzo, che hai solo bisogno di condividere il db-handle e utilizzarlo nei gestori 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

Hi Julien, grazie per la risposta. Non potevamo aspettarci una fonte migliore dell'autore del driver Go-MySQL! Sembra che ci potrebbe essere un errore di battitura nel codice quando ottengo un errore di compilazione: './main.go:18: impossibile assegnare * sql.DB a db (tipo sql.DB) in più assegnazioni' – Jason

+0

Scusa, ho risolto il problema digita ora @ fmt.Println.MKO che questo non funziona non è ancora vero. Il database/sql è progettato esattamente per casi d'uso simultanei come questo. –

+0

FYI, ecco alcuni esempi più semplici su come accedere a un DB nei gestori HTTP: https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/go/src/hello/hello.go –

Problemi correlati