我正在使用sqlx编写我的第一个 Go 项目,并想使用准备好的语句。
我不确定以一种很好的可管理方式初始化和保留 Prepared 语句变量的推荐做法是什么。
我希望它们只能从实际必须使用它们的代码部分访问,到目前为止,每个语句都由单个函数使用,因此全局变量不是一个好的选择(除了通常不受欢迎之外)。
在 C/C++ 中,我可能会使用函数静态变量并在第一次输入函数时对其进行初始化。这样,有关语句内容的信息和使用它的调用彼此接近。
但是据我目前所知,Go 中没有“方法静态变量”,那么有什么选择呢?
我找到了对 Closures 的引用,它们是匿名函数,但这是实现此目的的最佳方法吗?从“准备好的报表最佳实践”的角度来看,我的目标是正确的吗?
我处理这个问题的一种方法是初始化主函数中我想要“保持活动”的所有准备好的语句(即那些经常使用的语句),并将它们保存到一个映射中,然后将其作为参数传递给以下函数:需要访问准备好的语句。
这不满足只能从实际使用它们的函数访问的要求,但它确实避免了全局变量并防止在需要时重新准备它们。
使用闭包你可以做这样的事情:
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() 即可。这将满足您的要求。