以前我用php使用mongodb并查询我使用单例的数据库.这样我只实例化一次连接然后重用它:
class MDB{
protected static $instance;
public static function use(){
if(!self::$instance) self::$instance = new MongoClient();
$db = self::$instance->selectDB('DB_name');
return $db;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以创建类Cats,并使用类似这样的方法addCat和showCats:
MDB::use->{'cats'}->insert([...]);
MDB::use->{'cats'}->find([...]);
Run Code Online (Sandbox Code Playgroud)
现在我开始使用mongodb和node.js. Mongodb教程给我看了这样的事情:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
if(err) { return console.dir(err); }
var collection = db.collection('test');
var doc1 = {'hello':'doc1'};
collection.insert(doc1);
});
Run Code Online (Sandbox Code Playgroud)
这基本上告诉我,我必须将所有节点操作设置为connect内部的回调.阅读该人提供的类似问题:
当您的应用程序启动并重用db对象时,您可以打开一次MongoClient.connect.它不是单独的连接池,每个.connect都会创建一个新的连接池.
但我无法理解我应该如何使用它(例如我的猫类)?
Sca*_*ell 11
这是一种方法.您可以将数据库连接详细信息放在一个小模块中,在应用程序启动时对其进行初始化,然后从需要数据库连接的任何其他模块中使用该模块.这是我一直在使用的代码,并且在一个相当简单的内部应用程序中为我工作.
file: DataAccessAdapter.js
var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
var dbPort = 27017;
var dbHost = 'localhost';
var dbName = 'CatDatabase';
var DataBase = function () {
};
module.exports = DataBase;
DataBase.GetDB = function () {
if (typeof DataBase.db === 'undefined') {
DataBase.InitDB();
}
return DataBase.db;
}
DataBase.InitDB = function () {
DataBase.db = new Db(dbName, new Server(dbHost, dbPort, {}, {}), { safe: false, auto_reconnect: true });
DataBase.db.open(function (e, d) {
if (e) {
console.log(e);
} else {
console.log('connected to database :: ' + dbName);
}
});
}
DataBase.Disconnect = function () {
if (DataBase.db) {
DataBase.db.close();
}
}
DataBase.BsonIdFromString = function (id) {
var mongo = require('mongodb');
var BSON = mongo.BSONPure;
return new BSON.ObjectID(id);
}
Run Code Online (Sandbox Code Playgroud)
然后从server.js开始,当你的应用程序启动时:
// Startup database connection
require('./DataAccessAdapter').InitDB();
Run Code Online (Sandbox Code Playgroud)
当您需要使用数据库时,例如在" Cat.js "文件中,您可以执行以下操作:
var dataAccessAdapter = require('./DataAccessAdapter');
var Cat = function () {
if (!Cat.db) {
console.log('Initializing my Cat database');
Cat.db = dataAccessAdapter.GetDB();
}
if (!Cat.CatCollection) {
console.log('Initializing cats collection');
Cat.CatCollection = Cat.db.collection('Cats'); // Name of collection in mongo
}
return Cat;
}
module.exports = Cat;
Cat.Name = null;
Cat.HasFur = false;
Cat.Read = function (catId, callback) {
var o_id = dataAccessAdapter.BsonIdFromString(catId);
Cat.CatCollection.findOne({ '_id': o_id }, function (err, document) {
if (!document) {
var msg = "This cat is not in the database";
console.warn(msg);
callback(null, msg);
}
else {
callback(document);
}
});
}
Run Code Online (Sandbox Code Playgroud)
我希望这对于看到不同的方法至少有点帮助.我并不认为自己是专家,并且对此有一些反馈意见,但到目前为止,这个解决方案对我来说效果很好.
我赞成了Scampbell的解决方案,但他的解决方案应该加强imho.目前,它不是异步,两者InitDB并GetDB()应该有一个回调的属性.
因此,每当您将数据库更改为连接时,它都会失败,因为它会在有机会连接到数据库之前返回.如果始终连接到同一数据库,则该错误不存在(因此返回Database.db始终成功)
这是我对他的解决方案的错误修正/增强:
Database.InitDB = function (callback) {
if (_curDB === null || _curDB === undefined ||_curDB === '') {
_curDB = _dbName;
}
Database.db = new Db(_curDB,
new Server(_dbHost, _dbPort, {}, {}),
{ safe: false, auto_reconnect: true });
Database.db.open(function (err, db) {
if (err) {
console.log(err);
} else {
console.log('connected to database :: ' + _curDB);
if (callback !== undefined) {callback(db);}
}
});
};
Run Code Online (Sandbox Code Playgroud)
他的其他职能也是如此.还要注意if (callback部分,它允许Database.InitDB()在app.js/server.js的开头无需参数调用,无论你的主文件是什么.
((我应该把我的回复写成对Scampbell解决方案的评论,但我没有足够的声誉这样做.同样对他的解决方案感到荣幸,这是一个不错的起点))
这是在singleton上使用async等待的内容.在我的db.js中
var MongoClient = require('mongodb').MongoClient;
var DbConnection = function () {
var db = null;
var instance = 0;
async function DbConnect() {
try {
let url = 'mongodb://myurl.blablabla';
let _db = await MongoClient.connect(url);
return _db
} catch (e) {
return e;
}
}
async function Get() {
try {
instance++; // this is just to count how many times our singleton is called.
console.log(`DbConnection called ${instance} times`);
if (db != null) {
console.log(`db connection is already alive`);
return db;
} else {
console.log(`getting new db connection`);
db = await DbConnect();
return db;
}
} catch (e) {
return e;
}
}
return {
Get: Get
}
}
module.exports = DbConnection();
Run Code Online (Sandbox Code Playgroud)
并且在所有将使用相同连接的模块中
var DbConnection = require('./db');
async function insert(data) {
try {
let db = await DbConnection.Get();
let result = await db.collection('mycollection').insert(data);
return result;
} catch (e) {
return e;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10464 次 |
| 最近记录: |