在 Node JS 应用程序中实现单例 mongoDB DB 对象
Posted
技术标签:
【中文标题】在 Node JS 应用程序中实现单例 mongoDB DB 对象【英文标题】:Implementing singleton mongDB DB object in NodeJS application [duplicate] 【发布时间】:2018-10-18 16:56:59 【问题描述】:目前正在使用 express
,socket.io
的 nodeJS 后端开发,并使用 MongoDB 作为其数据库。我读到,实现将在整个应用程序中重用的单例数据库连接是一个好习惯。我试图实现这个还没有找到解决方案。我尝试使用this SO answer of go-oleg。
我复制了第一部分,外部 mongoUtil.js 文件,如下所示:
var MongoClient = require( 'mongodb' ).MongoClient;
var _db;
module.exports =
connectToServer: function( callback )
MongoClient.connect( "mongodb://localhost:27017/marankings", function( err, db )
_db = db;
return callback( err );
);
,
getDb: function()
return _db;
;
然后在我的 server.js 中,我像这样调用这个函数一次(我不做任何回调是必需的吗?)。
var mongoUtil = require( 'mongoUtil' );
mongoUtil.connectToServer( function( err )
// start the rest of your app here
);
然后当我在应用程序的另一个模块中尝试以下操作时:
const db = mongoDB.getDb();
router.post('/', (req, res, next) =>
console.log(db);
next();
)
未定义的日志
日志显示undefined
,因此我没有数据库实例。
问题:
为什么这不起作用,我该如何解决这个问题?
【问题讨论】:
我设法在个人项目中解决了这个问题,但我不知道这是否是最佳实践......我的代码使用的是 ecmascript 6.0 标准......如果你有兴趣...... .我可以把它的碎片... 问题太多。尝试一些最新的教程。您所指的答案假设对节点有一些基本经验,不幸的是已经过时了。 MongoClient.connect 返回客户端,而不是驱动程序 v3 以来的 db。 是的,我很感激,谢谢! 【参考方案1】:好的...所以,这可能是使用了一些过时的 Mongo,但这是我设法解决 DB 的单例部分的方法。免责声明:这是 Mongo 和 Ecmascript 6.0 的个人学习项目,因此不确定它是否遵循最佳实践,但它确实有效。
拳头,数据库连接:personnaDB.js
/************ Copyright ************/
/* Year: 2016
* Author: David Espino
*/
"use strict"
// Imports
const url = require('url'),
connectionUrl = process.env.CONNECTION_STRING || 'mongodb://localhost:27017/personna',
parsedUrl = url.parse(connectionUrl),
Db = require('mongodb').Db,
Server = require('mongodb').Server,
Connection = require('mongodb').Connection,
Q = require("q"),
mongoose = require("mongoose"),
dao = require('./personnaDao'),
autoIncrement = require( 'mongoose-auto-increment' );
// Symbol Keys
const _connKey = Symbol();
const _connInfoKey = Symbol();
const _monConnKey = Symbol();
const _dataModelsKey = Symbol();
const _autoIncrementKey = Symbol();
/**
* This class represents the DB Connection
*/
class PersonnaDb
/**
* Class Constructor
* @return [type] [description]
*/
constructor()
let mongoObject = null;
this[_connInfoKey] =
host: parsedUrl.hostname,
port: parseInt(parsedUrl.port, 10),
name: parsedUrl.pathname.substr(1),
user: parsedUrl.auth ? parsedUrl.auth.split(':')[0] : null,
password: parsedUrl.auth ? parsedUrl.auth.split(':')[1] : null
;
this._connInstance = null;
/**
* Opens the DB connection using regular mongo db access
* @return [type] [description]
*/
openConnection()
let deferred = Q.defer();
if (this[_connKey])
console.log('---> not need to create instance');
deferred.resolve(this[_connInfoKey]);
else
let $this = this;
const mongoObject = new Db('your-db', new Server(this[_connInfoKey].host, this[_connInfoKey].port, auto_reconnect: true ));
mongoObject.open(function(error, databaseConnection)
if (error) throw new Error(error);
console.log('---> Succesfully CREATED connection');
$this[_connKey] = databaseConnection;
// Initialize auto increment
autoIncrement.initialize(databaseConnection);
$this[_autoIncrementKey] = autoIncrement;
deferred.resolve($this);
);
return deferred.promise;
/**
* Opens a Mongo db connection
* @return [type] [description]
*/
openMongooseConnection()
mongoose.connect(connectionUrl);
// set the identity plugin
autoIncrement.initialize(mongoose.connection);
this[_autoIncrementKey] = autoIncrement;
// CONNECTION EVENTS
// When successfully connected
mongoose.connection.on('connected', function ()
console.log('Mongoose default connection open to ' + parsedUrl);
);
// If the connection throws an error
mongoose.connection.on('error',function (err)
console.log('Mongoose default connection error: ' + err);
);
// When the connection is disconnected
mongoose.connection.on('disconnected', function ()
console.log('Mongoose default connection disconnected');
);
// If the Node process ends, close the Mongoose connection
process.on('SIGINT', function()
mongoose.connection.close(function ()
console.log('Mongoose default connection disconnected through app termination');
process.exit(0);
);
);
this[_dataModelsKey] = dao.PersonaDataModels.GetModels(this[_autoIncrementKey]);
// require('../models/data/bodySectionModel');
dataModels()
return this[_dataModelsKey];
module.exports.PersonnaDb = PersonnaDb;
第二...服务设置(我的层需要 dbconnection)
服务 > include.js
const ModifierService = require('./modifierService').ModifierService;
const BodySectionService = require('./bodySectionService').BodySectionService;
module.exports = (dbConnection) =>
return
Modifier: new ModifierService(dbConnection),
BodySection: new BodySectionService(dbConnection),
服务示例(它基本上初始化了 mongo 模型。BodySectionService.js
class BodySectionService extends BaseService
constructor(db)
super(db.dataModels().BodySection); // this is the mongo model with the schema etc
然后是数据库初始化(并将数据库连接作为单例对象传递)
app.js
var express = require('express');
const PersonnaDb = require('./dao/personnaDb').PersonnaDb;
const dbConnection = new PersonnaDb();
var app = express();
// Open DB Connection
dbConnection.openMongooseConnection();
// get the services
const services = require('./services/include')(dbConnection);
// // This is the piece that I was not totally sure, making this available on the app
app.set('services', services);
app.set('dbAccess', dbConnection);
这就是我使用它的方式:
bodySectionController.js
router.get('/', function(req, res, next)
const bodySectionProxy = req.app.get("services").BodySection;
const logger = req.app.get("customLogger");
var result = bodySectionProxy.getBodySections().then((result) =>
res.json(result);
)
.fail((err) =>
logger.logError(err);
res.json(err.message);
)
.done();
);
module.exports = router;
我已经排除了关于如何在服务上设置模型的路径,因为您的问题只询问如何设置数据库。但如果你需要我,我也可以用它来扩展答案。
希望这能给你一个想法。
【讨论】:
以上是关于在 Node JS 应用程序中实现单例 mongoDB DB 对象的主要内容,如果未能解决你的问题,请参考以下文章