【问题标题】:How to reuse Db Connections in Nodejs and Express如何在 Nodejs 和 Express 中重用 Db 连接
【发布时间】:2019-02-24 21:14:25
【问题描述】:

我想知道在我的情况下重用数据库连接的最佳方法是在 NodeJs 和 express 中重用它的 couchbase 连接。 对于 Express 部分,我创建了一个像这样的中间件

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 级左右才能使用中间件。有没有更好的方法可以将连接/存储桶公开给正常功能?

【问题讨论】:

    标签: node.js express couchbase


    【解决方案1】:

    您是否尝试过将您的初始化代码从中间件函数中取出? Couchbase Documentation 没有显示它以这种方式使用。尽管该示例是在 vanilla Node.js 中。通过将其放置在中间件函数中,您将在每次服务器收到请求时重新连接到数据库。

    我在顶级 app.js 正文中连接到我的 Mongo 服务器,这允许连接持续存在。然后我可以在我的模型和控制器中导入我需要的猫鼬引用来概述如何获取某些数据,然后在相关路由端点内调用控制器的方法。

    已编辑以显示将存储桶分配为控制器类字段的示例

    在您的 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)
          )
    
        });
      }
    
    }
    

    然后从路由内部调用你的 Controller 方法

    router.get("/", function(req, res, next) {
    
      let searchParam = req.query.someParam;
    
      CouchController.doSomeQuery(searchParam)
        .then(result => {
          res.json(result);
        });
    
    });
    

    【讨论】:

    • 我得到了控制器/路由部分,因为我已经在使用它了。我不清楚的是如何从控制器访问定义的存储桶,因为我需要存储桶来进行实际调用
    • 您可以将存储桶变量分配为控制器构造函数中的字段。然后你将控制器导入到你的 app.js 中,并用你所有的其他初始化代码实例化它。要为构造函数提供对沙发基础连接的引用,您也可以在构造函数中执行此操作,或者在 app.js 中对其进行初始化并将其作为参数传递给构造函数。
    【解决方案2】:

    您可以创建一个专门的模块(例如db.js),在其中为您的连接池实现一个单例。

    // pseudo-code
    export const getDb = () => {
      let db
    
      if (!db) {
        const connection = createConnectionPool()
        db = connection.db
      }
    
      return db
    }
    

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

    【讨论】:

      猜你喜欢
      • 2013-04-24
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 2017-07-25
      • 1970-01-01
      • 2021-06-08
      • 1970-01-01
      相关资源
      最近更新 更多