gpt4 book ai didi

sql - 使用存储库模式时如何在 Go 中处理数据库连接?

转载 作者:行者123 更新时间:2023-12-05 04:26:50 25 4
gpt4 key购买 nike

假设我有一个非常简单的存储库接口(interface),它只从目标数据库读取数据:

type UserRepository interface {
read(ctx context.Context, id WHAT_TYPE_I_SHOULD_USE_HERE) models.User
}

注意:请注意,在 id 参数中,我不知道要使用什么作为 id 类型,因为 MongoDB 中的 id 是 ObjectId 并且在基于模式的数据库中,它可能是一个 UUID 字段。如果有帮助,我的主要数据库是 MongoDB,但我可能会切换到基于模式的数据库。

现在我有一个 MongoDBRepository 结构,它附加了 read():

type MongoDBRepository struct {
}

func (mo MongoDBRepository) read(ctx context.Context, id primitive.ObjectID) {
fmt.Printf("read user %s from MongoDB", id)
}

我有一个连接到 MongoDB 的方法:

func ConnectMongoDB() (*mongo.Client, context.CancelFunc) {
client, err := mongo.NewClient(options.Client().ApplyURI(configs.MongoURI()))
if err != nil {
log.Fatal(err)
}

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

err = client.Connect(ctx)

err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}

log.Print("Successfully connected to MongoDB!")

return client, cancel
}

现在,随着接口(interface)的实现,我们可以为 MySQL/PostgreSQLConnectMySQL/ConnectPostgreSQL 提供一个类似的存储库>.

我的主要功能是我应该如何处理连接到我当前的数据库存储库以及如何在我的 Controller 中使用它来读取或更新文档/记录?

当我将我的连接传递给 Controller ​​方法时,它的类型设置为 *mongo.Client 我怎样才能将它抽象出来,这样我获取数据库连接的 Controller 方法就不会绑定(bind)到目标数据库类型?

最佳答案

how should I handle connecting to my current database repository andhow to use it in my controllers to read or update a document/record

我一直在检查提供商文档以获取有关该问题的提示。

经过快速搜索,我在Github中找到了我需要的东西。 :

// Client is a handle representing a pool of connections to a MongoDB deployment. It is safe for concurrent use by
// multiple goroutines.

客户端是线程安全的,代表的不是单个连接,而是一个连接池。这意味着我可以在 Controllers/Repositories 的多个实例之间共享一个 Client 实例,并且客户端可以处理它。

从存储库开始。我们需要注入(inject)客户端:

type MongoDBRepository struct {
Client mongo.Client
}

根据当前的设计,存储库仅包含线程安全成员,因此它本质上是线程安全的。

这是在应用程序启动代码中创建存储库的代码:

repo := &MongoDBRepository{Client: client}

在 Controller 中,我们将Repository定义为接口(interface)类型,但我们将注入(inject)MongoDBRepository结构:

// Controller Code
type UserController struct {
Repo UserRepository
}

Controller 的启动代码也应该发生在应用程序之星上:

// App start 
controller := &UserController{Repo: repo}

要处理数据库特定类型 (id WHAT_TYPE_I_SHOULD_USE_HERE),您需要将它们实现为 Generics .它可能会使您的 Controller 代码变得相当复杂。考虑将这种复杂性隐藏在存储库中,并公开一些简单的东西,例如字符串或 uuid。

通过这种方法,您可以轻松地在不同的数据库之间切换。您需要更改的只是应用程序初始化 ( Composition Root),无需更改 Controller 代码。

附言多数据库支持非常昂贵。我们已经遇到了 ID 类型的问题。以后你应该准备好stop using any DB specific features and use only features available across all the databases .数据库事务是 Mongo 中不可用的重要 SQL 功能之一。在您完全致力于多种数据库类型之前权衡利弊。

更新:

  1. 使用 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法将 Controller 实现为结构体。
  2. 如果如上所述 main.go 中的结构创建实例。
  3. 使用 router.Handle 而不是 router.HandleFunc 将该结构集成到路由器中

使用结构,您应该可以更好地控制 Controller 依赖项的生命周期。

关于sql - 使用存储库模式时如何在 Go 中处理数据库连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72937159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com