mongodb - 如何正确断开 MongoDB 客户端
问题描述
据我了解,您必须在使用完 MongoDB 后断开与它的连接,但我不完全确定如何正确操作
var collection *mongo.Collection
var ctx = context.TODO()
func init() {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017/")
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err)
}
//defer client.Disconnect(ctx)
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected successfully")
collection = client.Database("testDB").Collection("testCollection") //create DB
}
有注释掉的函数调用
defer client.Disconnect(ctx)
,如果所有代码都发生在 main() 函数中,这将正常工作,但由于在 init() 执行后立即调用 defer,因此 main() 函数中的 DB 已经断开连接。
所以问题是——处理这个案子的正确方法是什么?
解决方案
您的应用程序需要在所有服务或存储库中连接 MongoDB 客户端,因此如果您在应用程序包中分离了 MongoDB 客户端连接和断开功能,则更容易。您不需要连接 MongoDB 客户端,如果您的服务器正在启动,如果您的服务或存储库需要 MongoDB 客户端连接,您可以先连接。
// db.go
package application
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"os"
)
var client *mongo.Client
func ResolveClientDB() *mongo.Client {
if client != nil {
return client
}
var err error
// TODO add to your .env.yml or .config.yml MONGODB_URI: mongodb://localhost:27017
clientOptions := options.Client().ApplyURI(os.Getenv("MONGODB_URI"))
client, err = mongo.Connect(context.Background(), clientOptions)
if err != nil {
log.Fatal(err)
}
// check the connection
err = client.Ping(context.Background(), nil)
if err != nil {
log.Fatal(err)
}
// TODO optional you can log your connected MongoDB client
return client
}
func CloseClientDB() {
if client == nil {
return
}
err := client.Disconnect(context.TODO())
if err != nil {
log.Fatal(err)
}
// TODO optional you can log your closed MongoDB client
fmt.Println("Connection to MongoDB closed.")
}
主要:
func main() {
// TODO add your main code here
defer application.CloseClientDB()
}
在您的存储库或服务中,您现在可以轻松获得 MongoDB 客户端:
// account_repository.go
// TODO add here your account repository interface
func (repository *accountRepository) getClient() *mongo.Client {
if repository.client != nil {
return repository.client
}
repository.client = application.ResolveClientDB()
return repository.client
}
func (repository *accountRepository) FindOneByFilter(filter bson.D) (*model.Account, error) {
var account *model.Account
collection := repository.getClient().Database("yourDB").Collection("account")
err := collection.FindOne(context.Background(), filter).Decode(&account)
return account, err
}
推荐阅读
- jasper-reports - 如何在 Jasper Report 中对列的数据求和
- wpf - 如何在 WPF DataGrid 中禁用行选择
- powershell - Powershell如何检查文本文件是否为空并忽略空格
- ios - 尝试使用 switch 语句来更改图像集
- php - PHP 处理表单,通过 POST 从 HTML 表单写入 CSV 文件
- node.js - 如何根据用户的日历事件触发 NodeJS 服务
- firebase - 如何在运行 Win10 IOT Core 的 RaspberryPi 的 UWP 应用程序中集成 firestore?
- django - 使用 Django Rest Framework 时在哪里执行附加操作
- javascript - 在 try catch 块中声明不可变变量,可以在块外访问?
- recursion - 从数字中减去 1(Prolog 中的递归)