在Go中初始化和保留预准备语句的推荐方法是什么?

时间:2015-04-12 06:15:59

标签: sql go sqlx

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

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

使用闭包你可以这样做:

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()。这符合您的要求。