3 回答

TA貢獻1893條經驗 獲得超10個贊
使用方法而不是函數。這允許您使用這些方法的接收器傳遞處理程序所需的任何信息:
type MyHandler struct {
DB *gorm.DB
}
func (m MyHandler) IndexHandler(w http.ResponseWriter, r *http.Request) {
// Use m.DB here
}
主要內容:
handler:=mypkg.MyHandler{DB:gormDB}
r.Get("/", handler.IndexHandler)
在某些情況下,閉包更有意義。
func GetIndexHandler(db *gorm.DB) func(http.ResponseWriter,*http.Request) {
return func(w http.ResponseWriter,req *http.Request) {
// Implement index handler here, using db
}
}
func main() {
...
r.Get("/", GetIndexHandler(db))

TA貢獻1797條經驗 獲得超4個贊
在數據庫/查詢函數本身中。我個人為控制器制作了一個單獨的包,為服務制作了一個單獨的包。我在控制器(具有我的處理程序函數)中處理所有請求驗證和HTTP內容。然后,如果一切都檢查出來,我打電話給一個服務包。服務包是調用數據庫以及任何其他服務或 API 集成的服務包。
然而,無論你在哪里調用數據庫,通常你都會調用一個包,該包具有一堆具有友好名稱的查詢函數,例如或類似名稱。好吧,該函數正是您傳遞或對象的位置。dbdb.GetAccountByIDdb*sql.DB*gorm.DB
一個例子是...
package db
func GetAccountByID(id int, db *gorm.DB) (*model.Account, error) {
if db == nil {
db = conn // conn is the package level db connection object
}
//...
}
通常,當服務器啟動時,我會創建數據庫連接(用作連接池),因此實際上沒有必要將其傳遞到函數中。那么,為什么要這樣做呢?嗯,這是因為測試。您不希望數據庫處理程序訪問包級數據庫連接對象,因為對該函數進行隔離測試變得更加困難。
因此,此函數簽名為您提供了可測試性,并且初始條件仍然使用單個中央數據庫連接對象(如果為數據庫值傳入),除非您正在測試,否則該對象始終是。ifnilnil
這只是一種方法,但我已經成功使用了多年。
- 3 回答
- 0 關注
- 108 瀏覽
添加回答
舉報