我处理这个问题的一种方法是在主函数中初始化我想要“保持活动状态”的所有准备好的语句(即那些经常使用的语句)并将它们保存到一个映射中,然后我将它作为参数传递给函数需要访问准备好的语句。
这不符合您只能从实际使用它们的函数访问的要求,但它确实避免了全局变量并防止在需要时重新准备它们。
使用闭包你可以做这样的事情:
func main() {
// initialize your database etc.
getData, stmt := initGetData(db) // db is *sql.DB, initGetData is the function below
defer stmt.Close()
myResult := getData()
}
func initGetData(db *sql.DB) ((func() string), *sql.Stmt) {
stmt, err := db.Prepare("SELECT something FROM some_table")
if err != nil {
log.Fatal(err)
}
return func() string {
var result string
err := stmt.QueryRow().Scan(&result)
if err != nil {
log.Fatal(err)
}
return result
}, stmt
}
这样做,您就拥有了带有进行查询的函数的准备好的语句。但是该语句仅在调用返回闭包的 initGetData() 函数时才准备好。闭包运行查询并可以访问调用 myQuery 时创建的准备好的语句。
然后,您只需在每次需要运行查询时使用 getData() 即可。这将满足您的要求。