2 回答
TA贡献1802条经验 获得超10个赞
您有三个选择:
使您的数据库连接池成为全局的,这样您就不必传递它。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 程序中访问数据库池的方法的优秀博客文章。
我可以给出的唯一严格建议是,您应该避免在请求上下文中传递数据库池,这是低效且不好的做法(请求上下文用于临时的、每个请求的对象)。
TA贡献1840条经验 获得超5个赞
您始终可以将“env”定义为全局变量。
但在大家讨厌我之前,这可不是什么好办法!您应该创建一个包,该包使用公共函数来封装对数据库的访问,以说明您的确切意图。
类似的东西
Package db
var config ....
func ShowTodos(params ... ) result {
your database access code here....
}
并从您的路由器功能访问它
db.ShowTodos(...)
- 2 回答
- 0 关注
- 163 浏览
添加回答
举报