2015-04-12 17 views
4

我正在使用sqlx編寫我的第一個Go項目,並且希望使用Prepared語句。在Go中初始化和保留預處理語句的建議方法是什麼?

我不確定什麼是建議的做法,以一個很好的可管理的方式初始化和保持Prepared語句變量。

我希望它們只能從實際使用它們的代碼部分訪問,到目前爲止,每個語句都由一個函數使用,所以全局變量不是一個好的選擇(除了通常被忽視之外) 。

在C/C++中,我可能會使用函數靜態變量,並在第一次輸入函數時對其進行初始化。這樣,關於聲明內容的信息和使用它的呼叫彼此接近。

但是從我所知道的到目前爲止Go上沒有「方法靜態變量」,那麼有什麼選擇?

我發現引用閉包,這是匿名函數,但這是實現這一目標的最佳方法嗎?我是否從「準備好的陳述最佳實踐」的角度來尋找正確的東西?

回答

1

我處理過的一種方法是在主函數中初始化我想要「保持活力」的所有準備好的語句(即那些經常使用的語句),並將它們保存到映射中,然後將其作爲參數傳遞到需要訪問準備好的語句的函數。

這不符合您只能從實際使用它們的函數訪問的要求,但它確實避免了全局性,並且可以避免在需要時重新準備它們。

使用閉包你可以做這樣的事情:

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

+0

是的,我也想過這個選項。每次調用方法時,它還具有不測試準備好的語句的優點。 但它也將初始化和使用分開,看起來有點古怪。如果可能的話,我寧願嘗試尋找更優雅的東西。 –

+0

@Amos Shapira - 好的,同意了。看到我更新的答案。 – IamNaN

+0

謝謝。我將不得不研究這個(我是一個前進),看看它對我有多好。 –

相關問題