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

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

Go and Gin:傳遞數據庫上下文的結構?

Go and Gin:傳遞數據庫上下文的結構?

Go
jeck貓 2021-12-20 10:13:20
我剛剛開始嘗試 Go,我希望用它重新實現一個用 node 編寫的 API 服務器。我在嘗試使用依賴注入將數據庫上下文作為 gin 中間件傳遞時遇到了障礙。到目前為止,我已將其設置為:main.go:package mainimport (        "fmt"        "runtime"        "log"        "github.com/gin-gonic/gin"        "votesforschools.com/api/public"        "votesforschools.com/api/models")type DB struct {        models.DataStore}func main() {        ConfigRuntime()        ConfigServer()}func Database(connectionString string) gin.HandlerFunc {        dbInstance, err := models.NewDB(connectionString)        if err != nil {                log.Panic(err)        }        db := &DB{dbInstance}        return func(c *gin.Context) {                c.Set("DB", db)                c.Next()        }}func ConfigRuntime() {        nuCPU := runtime.NumCPU()        runtime.GOMAXPROCS(nuCPU)        fmt.Printf("Running with %d CPUs\n", nuCPU)}func ConfigServer() {        gin.SetMode(gin.ReleaseMode)        router := gin.New()        router.Use(Database("<connectionstring>"))        router.GET("/public/current-vote-pack", public.GetCurrentVotePack)        router.Run(":1000")}模型/db.gopackage modelsimport (        "database/sql"        _ "github.com/go-sql-driver/mysql")type DataStore interface {        GetVotePack(id string) (*VotePack, error)}type DB struct {        *sql.DB}func NewDB(dataSource string) (*DB, error) {        db, err := sql.Open("mysql", dataSource)        if err != nil {                return nil, err        }        if err = db.Ping(); err != nil {                return nil, err        }        return &DB{db}, nil}但是我得到 public\public.go:10: db.GetVotePack undefined (type interface {} is interface with no methods)當我在調試器中檢查(使用帶有插件的 Webstorm)時,db 只是一個空對象。我正在努力做好并避免使用全局變量
查看完整描述

3 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

我認為不context應該用作 DI 容器:https : //golang.org/pkg/context/


包上下文定義了上下文類型,它在 API 邊界和進程之間攜帶截止日期、取消信號和其他請求范圍的值。


我寧愿使用:


package public


type PublicController struct {

        Database *DB

}


func (c *PublicController) GetCurrentVotePack(context *gin.Context) {

        votePack, err := c.Database.GetVotePack("c5039ecd-e774-4c19-a2b9-600c2134784d")

        if err != nil{

                context.String(404, "Votepack Not Found")

        }

        context.JSON(200, votePack)

}

并在 main 中配置您的控制器:


func main() {

        pCtrl := PublicController { Database: models.NewDB("<connectionstring>") }


        router := gin.New()

        router.GET("/public/current-vote-pack", pCtrl.GetCurrentVotePack)

        router.Run(":1000")

}


查看完整回答
反對 回復 2021-12-20
?
富國滬深

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

其中的值context.Keys都是 type interface{},因此在db將 type*DB轉換回該類型之前,將無法從 type 調用方法。


安全的方法:


db, ok := context.Keys["DB"].(*DB)

if !ok {

        //Handle case of no *DB instance

}

// db is now a *DB value

不太安全的方法,如果context.Keys["DB"]不是 type 的值,它會恐慌*DB:


db := context.Keys["DB"].(*DB)

// db is now a *DB value

Effective Go有一個關于這個的部分。


查看完整回答
反對 回復 2021-12-20
?
江戶川亂折騰

TA貢獻1851條經驗 獲得超5個贊

您需要類型斷言才能將接口 (db := context.Keys["DB"]) 轉換為有用的東西。例如,參見這篇文章:convert interface{} to int in Golang


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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