如何在Nodejs和Express中重复使用Db连接

3

我想知道在我的情况下,重用数据库连接的最佳方式是什么,对于NodeJs和Express来说,这个连接是Couchbase连接。 对于Express部分,我创建了一个类似于以下的中间件:

Original Answer翻译成:"最初的回答"

var couchbase = require('couchbase')
var config = require('../config/config')

module.exports = (req,res,next)=>{
  var cluster = new couchbase.Cluster(config.cluster)
  cluster.authenticate(config.userid, config.password)
  let bucket = cluster.openBucket(config.bucket);
  bucket.manager().createPrimaryIndex(function() {});
  req.bucket = bucket;
  req.N1qlQuery = couchbase.N1qlQuery;
  next();
}

在 Express 应用程序中,由于我告诉它这样做,所以它能正常工作。"最初的回答"。
const dbSessionMiddleware = require('../middleware/couch')
app.use(dbSessionMiddleware) 

我使用 req.bucket 访问它。我的问题是,我的应用程序中有控制器,它们可能会调用一个帮助函数,然后再调用另一个函数来获取一些数据。我想避免将请求对象向下传递5个级别以上才能使用中间件。是否有更好的方法可以将连接/桶暴露给普通函数?

2个回答

3
你是否尝试将初始化代码从中间件函数中取出?Couchbase文档没有展示它是以这种方式使用的。虽然该示例是在原生Node环境下编写的。将其放置在中间件函数中,每当服务器接收到请求时,都会重新连接到数据库。
我在顶层app.js主体中连接到Mongo服务器,这使连接得以保持。然后我可以在我的Models和Controller中导入所需的mongoose引用,以概述如何获取特定数据,然后在相关路由端点内调用控制器的方法。
编辑为一个示例显示分配bucket作为控制器类字段。 在你的app.js中:
const couchbase = require("couchbase");
const config = require("../config/config");

// ...app.js

const CouchController = require("../controllers/CouchController")(couchbase, config);

// app.js...

在你的控制器中

class CouchController {

  constructor(couchbase, config) {
    // You may either pass couchbase and config as params, or import directly into the controller
    this.cluster = new couchbase.Cluster(config.cluster);
    this.cluster.authenticate(config.userid, config.password);
    this.bucket = cluster.openBucket(config.bucket);
    this.N1qlQuery = couchbase.N1qlQuery;
  }

  doSomeQuery(queryString, callback) {

    // Use your query however its meant to be used. I'm not familiar with couchbase queries.
    this.bucket.manager().createPrimaryIndex(function() {

      this.bucket.query(
        this.N1qlQuery.fromString("SELECT * FROM bucketname WHERE $1 in interests LIMIT 1"),
        [queryString],
        callback(err, result)
      )

    });
  }

}

然后从路由中调用您的控制器方法

router.get("/", function(req, res, next) {

  let searchParam = req.query.someParam;

  CouchController.doSomeQuery(searchParam)
    .then(result => {
      res.json(result);
    });

});

我已经获取了控制器/路由部分,因为我已经在使用它。但我不清楚如何从控制器中访问定义的存储桶,因为我需要该存储桶来进行实际调用。 - MisterniceGuy
你可以将bucket变量分配为控制器构造函数中的一个字段。然后,您可以将控制器导入到app.js中,并使用所有其他init代码实例化它。为了给构造函数一个对couchbase连接的引用,您可以在构造函数中执行此操作,或者在app.js中初始化它并将其作为参数传递给构造函数。 - Drowsy

1
你可以创建一个专门的模块(例如 db.js),在其中实现连接池的单例。
// pseudo-code
export const getDb = () => {
  let db

  if (!db) {
    const connection = createConnectionPool()
    db = connection.db
  }

  return db
}

这个函数可以在你的中间件和代码的其他部分进行导入。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接