亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

GoLang:在數據庫中丟失范圍

GoLang:在數據庫中丟失范圍

Go
30秒到達戰場 2021-10-04 15:59:40
Go 新手,來自 .Net-land,所以請耐心等待......希望能得到一些關于構建我的 Go 應用程序的指導,特別是在管理和重用數據庫連接方面。我已將我的 db 代碼拆分為一個包,以允許將 db-lookups 放入像存儲庫層一樣處理 sql 查找的包中。我希望能夠靈活地將我的 db 層與我的應用程序服務分離,以便在必要時輕松替換我的數據庫?;旧希艺趯ふ矣嘘P如何以及何時處理 sql connect 并在應用程序中保存 sql.DB 指針的一些指導。我需要在 main.go 中保留一個全局指針還是可以在我的 mysql 包中管理連接?這是我的代碼:package mysqlstorageimport (    "database/sql"    "fmt"    "log"    "types")var db *sql.DBfunc Connect() {    db, dberr := sql.Open(“<CONNECTION_STRING>“)    if dberr != nil {        fmt.Println(dberr)    }}func SaveUser(u types.User) {    // use db here!     ....}func GetUser(id string) types.User {    // use db here!    ....}在運行我的 main.go 并使用我的 userservices 包嘗試保存用戶時,我遇到了一個問題,我似乎失去了我的指針范圍:-2015/05/03 17:49:08 http: panic serving [::1]:50106: runtime error: invalid memory address or nil pointer dereference goroutine 7 [running]: net/http.func·011() /usr/local/Cellar/go/1.4.2/libexec/src/net/http/server.go:1130 +0xbb database/sql.(*DB).conn(0x0, 0x10, 0x0, 0x0)   /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:634 +0x7ae database/sql.(*DB).Ping(0x0, 0x0, 0x0)    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:462 +0x3a mysqlstorage.SaveUser(0x0, 0xc20805425a, 0x7, 0xc208054280, 0x11, 0xc208054268, 0x6, 0xc208054274, 0x5)    /Users/<USERNAME>/Desktop/go/<APPNAME>/api/src/mysqlstorage/mysqlstorage.go:24    +0x35 services.CreateUser(0x57c148, 0xc2080563c0, 0xc2080329c0)     /Users/<USERNAME>/Desktop/go/<APPNAME>/api/src/services/userservices.go:30    +0x398 net/http.HandlerFunc.ServeHTTP(0x3d02a0, 0x57c148, 0xc2080563c0, 0xc2080329c0)   任何指導將不勝感激!謝謝你們!
查看完整描述

2 回答

?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

我認為您的問題是由于您使用了操作員db,Connect()范圍被遮蔽了:=。如果你改變你的方法來聲明一個dberrvar:


func Connect() {

    var dberr error

    db, dberr = sql.Open(“<CONNECTION_STRING>“)


    if dberr != nil {

        fmt.Println(dberr)

    }

}

您的代碼將按預期工作


查看完整回答
反對 回復 2021-10-04
?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

您超出范圍是因為您正在通過db, err :=賦值創建一個局部變量 db?,然后在 Connect func 返回時超出范圍。

一般就使用sql.DB

從database/sql 包:

DB 是表示零個或多個底層連接池的數據庫句柄。多個 goroutine 并發使用是安全的。

sql 包自動創建和釋放連接;它還維護一個空閑連接的空閑池。

返回的數據庫對于多個 goroutine 并發使用是安全的,并維護自己的空閑連接池。因此,應該只調用一次 Open 函數。很少需要關閉數據庫。

也就是說,您想打開連接一次,然后在整個過程中保持打開狀態。這樣,當您完成(或遇到致命或恐慌)時實際關閉它的唯一可靠方法是defer db.Close()在打開它后立即執行慣用的 go?,這需要在主函數中完成。

您仍然可以將 Connect 函數保留在您的包中,并使用它來初始化全局包變量 db,但從 main 調用一次并將 *sql.DB 返回到 main,以便您可以延遲 db.Close()。


查看完整回答
反對 回復 2021-10-04
  • 2 回答
  • 0 關注
  • 271 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號