5

我正在使用sqlx编写我的第一个 Go 项目,并且想使用 Prepared 语句。

我不确定以一种易于管理的方式初始化和保留 Prepared 语句变量的推荐做法是什么。

我希望它们只能从实际上必须使用它们的代码部分访问,到目前为止,每个语句都由一个函数使用,因此全局变量不是一个好的选择(除了通常不被接受之外)。

在 C/C++ 中,我可能会使用函数静态变量并在第一次输入函数时对其进行初始化。这样,关于语句内容和使用它的调用的信息就彼此接近了。

但是据我所知,到目前为止,Go 中没有“方法静态变量”,那么还有什么替代方法呢?

我找到了对闭包的引用,它们是匿名函数,但这是实现这一目标的最佳方法吗?从“准备好的陈述最佳实践”的角度来看,我的目标是正确的吗?

4

1 回答 1

2

我处理这个问题的一种方法是在主函数中初始化我想要“保持活动状态”的所有准备好的语句(即那些经常使用的语句)并将它们保存到一个映射中,然后我将它作为参数传递给函数需要访问准备好的语句。

这不符合您只能从实际使用它们的函数访问的要求,但它确实避免了全局变量并防止在需要时重新准备它们。

使用闭包你可以做这样的事情:

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() 即可。这将满足您的要求。

于 2015-04-12T06:50:57.783 回答