目前,我尝试使用Go创建一个小型Web项目,以在服务器上进行数据处理。
我尝试将数据库连接传递给我的HandlerFunc(tions),但是它没有按预期工作。我对golang相当陌生,因此也许我不了解该lang的一些基本原理。
我的主要功能如下:
func main() { db, err := config.NewDB("username:password@/databasename?charset=utf8&parseTime=True") if err != nil { log.Panic(err) } env := &config.Env{DB: db} router := NewRouter(env) log.Fatal(http.ListenAndServe(":8080", router)) }
我的路由器:
func NewRouter(env *config.Env) *mux.Router { router := mux.NewRouter().StrictSlash(true) for _, route := range routes { var handler http.Handler handler = route.HandlerFunc handler = Logger(handler, route.Name) router. Methods(route.Method). Path(route.Pattern). Name(route.Name). Handler(handler) } return router }
和我的路线:
type Route struct { Name string Method string Pattern string HandlerFunc http.HandlerFunc } type Routes []Route var routes = Routes{ Route{ "Index", "GET", "/", controller.Index, }, Route{ "Show", "GET", "/todos/{todoId}", controller.TodoShow, }, Route{ "Create", "POST", "/todos", controller.TodoCreate, }, }
所以-如何将我的“ env”(或env.DB)传递给FuncHandlers?我尝试了很多东西,但没有一个起作用。
您有三种选择:
sql.DB
var db *sql.DB func main() { var err error db, err = sql.Open(...) // Now accessible globally, no need to pass it around // ... }
func SomeHandler(db *sql.DB) http.HandlerFunc { fn := func(w http.ResponseWriter, r *http.Request) { res, err := db.GetThings() // etc. } return http.HandlerFunc(fn) } func main() { db, err := sql.Open(...) http.HandleFunc("/some-route", SomeHandler(db)) // etc. }
type AppHandler struct { Handler func(env *config.Env, w http.ResponseWriter, r *http.Request) Env *config.Env } // ServeHTTP allows your type to satisfy the http.Handler interface. func (ah *AppHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ah.Handler(ah.Env, w, r) } func SomeHandler(env *config.Env, w http.ResponseWriter, r *http.Request) { res, err := env.DB.GetThings() // etc. }
请注意,(无耻的插件!)我已经详细介绍了最后一种方法,Alex Edwards的博客文章也很出色,还介绍了在Go程序中访问数据库池的方法。
我能提供的唯一严格建议是,您应该避免在请求上下文中传递数据库池,这效率低下并且不是一种很好的做法(请求上下文是针对每个请求的临时对象)。