为了账号安全,请及时绑定邮箱和手机立即绑定

与多个包共享全局定义的 db conn

与多个包共享全局定义的 db conn

Go
GCT1015 2021-10-18 16:44:43
我已经阅读了一些关于我们如何处理数据库连接的 StackOverflow 答案。由于它是一个池,我们可以全局定义它并在多个 goroutine 中使用它,它是安全的。我遇到的问题是我已将 REST API 拆分为多个包。这些包中的每一个都需要一个 db 连接,所以我在启动时打开了一个数据库连接。但即使我全局定义连接,它也只是在包级别。我该怎么做才能在多个包之间共享它?对于某些上下文,我在我的应用程序中使用 PostgreSQL 驱动程序和 gin-gonic。
查看完整描述

3 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

还可以选择创建另一个包来保存与数据库连接相关的设置。然后它可以有一个包级全局,它可以main在任何导入它的包中初始化和使用。


这样,您可以明确地看到正在导入数据库包。这是一些示例代码。


package database


var (

    // DBCon is the connection handle

    // for the database

    DBCon *sql.DB

)

package main


import "myApp/database"


func main() {


    var err error

    database.DBCon, err = sql.Open("postgres", "user=myname dbname=dbname sslmode=disable")


}

package user


import "myApp/database"


func Index() {

    // database handle is available here

    database.DBCon


    ...

}


查看完整回答
反对 回复 2021-10-18
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

更新


我最终使用package config来初始化数据库,在应用程序开始时,它非常好,因为您不必将任何不需要的参数传递给函数。


原来的


我仍然是 golang 世界的新手,但我正在处理同样的问题,方法是在主包中声明局部变量,在我的情况下是 package app


var mongoClient *mongo.Client

var mongoCtx context.Context

var mongoCancelCtx context.CancelFunc

然后我将它们传递给内部的数据库文件package config以连接到数据库,并使用传递的指针来分配结果。


# app/app.go


var mongoClient *mongo.Client

var mongoCtx context.Context

var mongoCancelCtx context.CancelFunc

config.BootstrapDatabase(&mongoClient, &mongoCtx, &mongoCancelCtx)

# app/config/database.go


// BootstrapDatabase ...

func BootstrapDatabase(mongoClient **mongo.Client, ctx *context.Context, cancel *context.CancelFunc) {

    *ctx, *cancel = context.WithTimeout(context.Background(), 10*time.Second)


    client, err := mongo.Connect(*ctx, options.Client().ApplyURI(os.Getenv("MONGO_URI")))

    if err != nil {

        panic(err)

    }


    if err := client.Ping(*ctx, readpref.Primary()); err != nil {

        panic(err)

    }


    *mongoClient = client


    fmt.Println("Successfully connected and pinged.")

}

然后我创建一个数据库引用并将它传递给将使用它的每个包。



# app/app.go


db := mongoClient.Database(os.Getenv("MONGO_DATABASE"))

repositories.BootstrapRepositories(db)


e := echo.New()

routes.BootstrapRoutes(e, db)

所以这个想法是app/app.go在我的应用程序中的高级包中声明数据库引用并根据需要传递它,例如在我的package routes


#app/app.go



// BootstrapRoutes ...

func BootstrapRoutes(e *echo.Echo, db *mongo.Database) {


    // Set middleware

    e.Use(middleware.Logger())

    e.Use(middleware.Recover())


    // Users related routes

    e.POST("/api/users", controllers.CreateUser)


    // Starte web server

    e.Logger.Fatal(e.Start(":4242"))

}

我仍在试验它,我不知道这种方法是否适用于许多端点,或者我需要尝试将它分离到自己的包中,如本期第一个线程中所建议的那样。


请分享您的想法,我很高兴收到您的来信。


查看完整回答
反对 回复 2021-10-18
  • 3 回答
  • 0 关注
  • 204 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信