2013-06-29 28 views
34

Git noob'dur ve Go'da mysql bağlantısı açma ve daha sonra http işleyicileri arasında paylaşmanın tam örneklerini bulamıyorum. İşte kodum şu ana kadar HomeHandler'ımda main() 'da açtığım db bağlantısını nasıl kullanırdım?http goroutines arasında mysql bağlantısı nasıl paylaşılır?

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

} 

cevap

55

Veritabanı/sql paketi, bağlantı havuzunu sizin için otomatik olarak yönetir.

sql.Open(..), bağlantı havuzunu tek bir bağlantı değil, bir bağlantı havuzu temsil eden bir tanıtıcı döndürür. Veritabanı/sql paketi, havuzdaki tüm bağlantılar meşgulse otomatik olarak yeni bir bağlantı açar.

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

Merhaba Julien sayesinde cevaplanması için:

sadece db-kolu paylaşmak ve HTTP işleyicileri kullanmak gerektiğini, kodunuzda bunun anlamı uygulanır. Go-MySQL Sürücüsünün yazarından daha iyi bir kaynak beklemiyordum! Bir derleme hatası alıyorum kodda bir yazım hatası olabilir gibi görünüyor: './main.go:18: db (sql.DB yazın) birden çok atama 'sql.DB atayamazsınız' – Jason

+0

Üzgünüz, şimdi yaz. Bu çalışmayan @ fmt.Println.MKO hala doğru değil. Veritabanı/sql, tam olarak bu gibi kullanım durumları için tasarlanmıştır. –

+0

FYI, HTTP işleyicilerinde bir DB'ye nasıl erişileceğine dair birkaç basit örnek: https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/go/src/hello/hello.go –

İlgili konular