我正在使用sqlx编写我的第一个Go项目,并希望使用Prepared语句。
我不确定建议的做法是以一种易于管理的方式初始化和保留Prepared语句变量。
我希望它们只能从实际必须使用它们的代码部分访问,到目前为止,每个语句都由单个函数使用,因此全局变量不是一个好的选择(除了通常不赞成)。
在C / C ++中,我可能会使用函数静态变量,并在第一次输入函数时对其进行初始化。这样,有关语句内容和使用它的调用的信息彼此接近。
但据我所知,到目前为止Go中没有“方法静态变量”,那么还有什么选择呢?
我找到了对Closures的引用,它们是匿名函数,但这是实现此目的的最佳方法吗?我是从“准备好的陈述最佳实践”的角度来瞄准正确的事情吗?
答案 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()。这符合您的要求。