如何在 Go 中重用 MongoDB 连接

我想将用 Go 编写的服务器与 MongoDB 连接,但我不知道如何以有效的方式做到这一点。我发现几个例子实现了它,如下所示。


库/mongodb/client.go


package mongodb


import (

    "context"

    "log"

    "project/keys"


    "go.mongodb.org/mongo-driver/mongo"

    "go.mongodb.org/mongo-driver/mongo/options"

)


func GetClient() *mongo.Database {

    client, err := mongo.Connect(

        context.Background(),

        options.Client().ApplyURI(keys.GetKeys().MONGO_URI),

    )


    if err != nil {

        log.Fatal(err)

    }


    return client.Database(keys.GetKeys().MONGO_DB_NAME)

}

服务/用户/findOne.go


package userservices


import (

    "context"

    "log"

    "project/libs/mongodb"

    "project/models"


    "go.mongodb.org/mongo-driver/bson"

)


func FindOne(filter bson.M) (models.User, error) {

    var user models.User


    collection := mongodb.GetClient().Collection("users")

    result := collection.FindOne(context.TODO(), filter)


    if result.Err() != nil {

        return user, result.Err()

    }


    if err := result.Decode(&user); err != nil {

        log.Println("Failed to decode user with error:", err)

        return user, err

    }


    return user, nil

}

该GetClient函数返回一个数据库实例,然后在整个应用程序中使用该实例。这似乎有效,但我想知道这是否真的是最佳实践,因为每次请求新客户端时似乎都会创建一个新连接,如第二个代码片段所示,或者该假设是否不正确?我还考虑过转换GetClient为单例,它总是返回相同的数据库实例,但在这种情况下如何处理丢失的连接?谢谢


慕容3067478
浏览 89回答 3
3回答

牛魔王的故事

我就是这样做的。在服务启动时执行一次,然后将 MongoDatastore 对象传递给编排器、服务层和存储库层。我正在使用 mongo 的“github.com/mongodb/mongo-go-driver/mongo”驱动程序。我认为它在内部监视并回收空闲连接。因此,只要对 mongo.Client 对象的引用不丢失,我们就不必担心连接中断。const CONNECTED = "Successfully connected to database: %v"type MongoDatastore struct {    db      *mongo.Database    Session *mongo.Client    logger  *logrus.Logger}func NewDatastore(config config.GeneralConfig, logger *logrus.Logger) *MongoDatastore {    var mongoDataStore *MongoDatastore    db, session := connect(config, logger)    if db != nil && session != nil {        // log statements here as well        mongoDataStore = new(MongoDatastore)        mongoDataStore.db = db        mongoDataStore.logger = logger        mongoDataStore.Session = session        return mongoDataStore    }    logger.Fatalf("Failed to connect to database: %v", config.DatabaseName)    return nil}func connect(generalConfig config.GeneralConfig, logger *logrus.Logger) (a *mongo.Database, b *mongo.Client) {    var connectOnce sync.Once    var db *mongo.Database    var session *mongo.Client    connectOnce.Do(func() {        db, session = connectToMongo(generalConfig, logger)    })    return db, session}func connectToMongo(generalConfig config.GeneralConfig, logger *logrus.Logger) (a *mongo.Database, b *mongo.Client) {    var err error    session, err := mongo.NewClient(generalConfig.DatabaseHost)    if err != nil {        logger.Fatal(err)    }    session.Connect(context.TODO())    if err != nil {        logger.Fatal(err)    }    var DB = session.Database(generalConfig.DatabaseName)    logger.Info(CONNECTED, generalConfig.DatabaseName)    return DB, session}您现在可以按如下方式创建存储库:-type TestRepository interface{    Find(ctx context.Context, filters interface{}) []Document, error}type testRepository struct {    store      *datastore.MongoDatastore}func (r *testRepository) Find(ctx context.Context , filters interface{}) []Document, error{    cur, err := r.store.GetCollection("some_collection_name").Find(ctx, filters)    if err != nil {        return nil, err    }    defer cur.Close(ctx)    var result = make([]models.Document, 0)    for cur.Next(ctx) {        var currDoc models.Document        err := cur.Decode(&currDoc)        if err != nil {            //log here            continue        }        result = append(result, currDoc)    }    return result, err}

人到中年有点甜

我这样做解决了它var CNX = Connection()func Connection() *mongo.Client {    // Set client options    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")    // Connect to MongoDB    client, err := mongo.Connect(context.TODO(), clientOptions)    if err != nil {        log.Fatal(err)    }    // Check the connection    err = client.Ping(context.TODO(), nil)    if err != nil {    log.Fatal(err)    }    fmt.Println("Connected to MongoDB!")    return client  }//calll connection func main() {      collection := db.CNX.Database("tasks").Collection("task") }output "Connected to MongoDB!"

慕田峪4524236

我所做的是这样的:我有一个app.go文件来在我创建的config文件夹中建立mongoDB 连接func Connection() *mongo.Client {if err := godotenv.Load(); err != nil {    log.Println("No .env file found")}uri := os.Getenv("MONGODB_URI")if uri == "" {    log.Fatal("You must set your 'MONGODB_URI' environmental variable. See\n\t https://www.mongodb.com/docs/drivers/go/current/usage-examples/#environment-variable")}// Set client optionsclientOptions := options.Client().ApplyURI(uri)// Connect to MongoDBclient, err := mongo.Connect(context.TODO(), clientOptions)if err != nil {    log.Fatal(err)}// Check the connectionerr = client.Ping(context.TODO(), nil)if err != nil {    log.Fatal(err)}fmt.Println("Connected to MongoDB!")return client}我在另一个名为employee.go的文件中调用了这个函数,该文件位于模型文件夹中var CNX = config.Connection()func (e *Employee) CreateEmployeeDetails() *Employee {    coll := CNX.Database("employee").Collection("detail")    fmt.Println(coll)    result, err := coll.InsertOne(context.TODO(), e)    fmt.Printf("Inserted document with _id: %v\n", result.InsertedID)    if err != nil {        panic(err)    }    return e}
打开App,查看更多内容
随时随地看视频慕课网APP