您有三种选择:
- 将数据库连接池设置为全局,这样就不必传递它。
sql.DB
对于并发访问是安全的,这是最简单的方法。缺点是它使测试更加困难,并且混淆了池的“来源”-例如
var db *sql.DB func main() { var err error db, err = sql.Open(...) // Now accessible globally, no need to pass it around // ... }
- 将您的处理程序包装在一个闭包中,以使内部处理程序可以访问它。您需要对此进行调整,以适应您的跨路线范围方法(这有点使IMO变得晦涩,使我更难以查看存在的路线,但是我离题了),例如:
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程序中访问数据库池的方法。
我能提供的唯一严格建议是,您应该避免在请求上下文中传递数据库池,这效率低下并且不是一种很好的做法(请求上下文是针对每个请求的临时对象)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)