node.js對mongodb的連接&增刪改查(附async同步流程控制)
阿新 • • 發佈:2017-12-21
color var literal int lba node () n! node.js
1.啟動mongodb數據庫
官網下載mongodb數據庫
在mongodb根目錄下創建文件夾:假設取名為test。
我們認為test就是mongodb新建的數據庫一枚。
創建批處理文件 xxx.bat,內容如下:
運行e盤mongodb文件夾下bin目錄下的 mongod.exe,參數為
-dbpath E:\mongodb\test。
E:\mongodb\bin\mongod.exe -dbpath E:\mongodb\test
這樣就啟動了mongodb下test數據庫的服務器。
2.加載mongodb模塊
在我們的node.js項目中直接npm入mongodb模塊
npm install mongodb --save
3.依賴mongodb模塊
在想要寫對mongodb的增刪改查邏輯的js文件下加入以下依賴
var mongo = require("mongodb");
4.通用小函數
寫了幾個通用的小函數,最後創建一個對象,將函數全都掛到對象上,最後把對象exports出去即可。
/**
* 創建數據庫服務器並開發名為databaseName的數據庫
* @param host ip
* @param port 端口
* @param databaseName
* @return 打開失敗返回-1 ,成功返回database
*/
function openDatabase(host,port,databaseName){
//創建數據庫所在的服務器
var server = new mongo.Server(host, port, {auto_reconnect: true});
var db = new mongo.Db(databaseName, server, {safe: true});
db.open(function (err, db) {
if (err) {
console.log(‘打開數據庫失敗‘);
return -1;
}
else {
console.log(‘打開數據庫成功‘);
}
});
return db;
}
/**
* 連接數據集合
* @param db 數據庫
* @param collectionName 數據集合名稱
* @return 成功返回collection,失敗返回-1
*/
function openCollection(db,collectionName){
db.collection(collectionName,{safe:true},function(errcollection,collection){
if(!errcollection){
console.log(‘連接數據集合成功‘);
return collection;
}else{
console.log(‘連接數集合失敗‘);
return -1;
}
});
}
/**
* 插入數據
* @param collection
* @param tmp 要插入的數據
* @return 成功返回collection,失敗返回-1
*/
function insertCollection(collection,tmp){
//var tmp = {username:‘hello‘,password:1};
collection.insert(tmp,{safe:true},function(err, result){
if(err){
console.log(‘傳入數據集合失敗‘+tmp);
return -1;
}else {
console.log(‘插入數據集合成功‘+result);
}
});
return collection;
}
/**
* 查詢數據集合 沒有條件
* @param collection
* @return 成功返回查詢到的數據集合內容,失敗返回-1
*/
function findCollectionNoCondition(collection){
collection.find().toArray(function(errfind,cols){
if(!errfind){
console.log(‘查詢數據集合成功‘+JSON.stringify(cols));
return JSON.stringify(cols);
}else {
console.log(‘查詢數據集合失敗‘);
return -1;
}
});
}
/**
* 查詢數據集合 有條件
* @param collection
* @return 成功返回查詢到的數據集合內容,失敗返回-1
*/
function findCollectionHasCondition(collection,tmp){
collection.find(tmp).toArray(function(errfind,cols){
if(!errfind){
console.log(‘查詢數據集合成功‘+JSON.stringify(cols));
return JSON.stringify(cols);
}else {
console.log(‘查詢數據集合失敗‘);
return -1;
}
});
}
/**
* 刪除數據集合
* @param collection
* @param tmp
* @return 成功返回數據集合,失敗返回-1
*/
function removeCollection(collection,tmp){
//var tmp = {username:‘hello‘,password:1};
collection.remove(tmp,{safe:true},function(err, count){
if(err){
console.log(‘刪除數據集合失敗‘+tmp);
return -1;
}else {
console.log(‘刪除數據集合成功‘+count);
return collection;
}
});
}
5.async模塊解決node.js異步架構下同步邏輯的實現
看到《超實用的node.js代碼段》這本書上,講到Node.js是異步I/O驅動,所以在我們順序運行上面的幾個函數的時候,一定會遇到一個問題:如果前面de函數耗時長,那麽後面的函數不會等前面的函數運行完,而是直接運行。但是我的前一個函數的運行結果是要被後一個函數使用的呀。
這時候就需要在異步I/O下進行串行控制流控制。
書中介紹了async模塊,手續愛你第三方引入。
npm install async --save
- 1
require進來
var async=require("async");
- 1
使用方法:
Nodejs異步流程控制Async
我這裏使用的是waterfall瀑布模式流程控制
github waterfall機制使用demo
然後我就天真的使用了
//使用async瀑布模型流程控制執行 數據庫的連接查詢
async.waterfall([
function(callback){
var db;
db=user.openDatabase("localhost",27017,"test");
callback(null,db);
},
function(db,callback){
var collection;
if(db!=-1){
collection=user.openCollection(db,‘users‘);
}
callback(null,collection);
},
function(collection,callback){
var res;
if(collection!=-1){
res=user.findCollectionNoCondition(collection);
console.log(res);
callback(null,3);
}
}
],function(err,result){
console.log("async瀑布模型流程控制執行成功"+result);
})
結果還是第二個函數先於第一個函數運行成功,導致第三個函數不能正確運行。
**********************************************************************
一、使用模塊Q的promise機制實現數據庫操作的同步問題
1.install
npm install q --save
2.require
var Q=require(‘q‘);
3.重寫數據庫CRUD操作方法
/**
* 創建數據庫服務器並開發名為databaseName的數據庫
* @param host ip
* @param port 端口
* @param databaseName
* @return 打開失敗返回-1 ,成功返回database
*/
function openDatabase(host,port,databaseName,collectionName){
//創建數據庫所在的服務器
var deferred = Q.defer();
var server = new mongo.Server(host, port, {auto_reconnect: true});
var db = new mongo.Db(databaseName, server, {safe: true});
db.open(function (err, db) {
if (err) {
console.log(‘打開數據庫失敗‘);
deferred.reject(err);
}
else {
console.log(‘打開數據庫成功‘);
deferred.resolve([db,collectionName]);
}
});
return deferred.promise;
}
/**
* 連接數據集合
* @param db 數據庫
* @param collectionName 數據集合名稱
* @return 成功返回collection,失敗返回-1
*/
function openCollection(db,collectionName){
var deferred = Q.defer();
db.collection(collectionName,{safe:true},function(errcollection,collection){
if(!errcollection){
console.log(‘連接數據集合成功‘);
deferred.resolve(collection);
}else{
console.log(‘連接數集合失敗‘);
deferred.reject(errcollection);
}
});
return deferred.promise;
}
/**
* 插入數據
* @param collection
* @param tmp 要插入的數據
* @return 成功返回collection,失敗返回-1
*/
function insertCollection(collection,tmp){
//var tmp = {username:‘hello‘,password:1};
collection.insert(tmp,{safe:true},function(err, result){
if(err){
console.log(‘傳入數據集合失敗‘+tmp);
return -1;
}else {
console.log(‘插入數據集合成功‘+result);
}
});
return collection;
}
/**
* 查詢數據集合 沒有條件
* @param collection
* @return 成功返回查詢到的數據集合內容,失敗返回-1
*/
function findCollectionNoCondition(collection){
var deferred = Q.defer();
collection.find().toArray(function(errfind,cols){
if(!errfind){
console.log(‘查詢數據集合成功‘+JSON.stringify(cols));
deferred.resolve(JSON.stringify(cols));
}else {
console.log(‘查詢數據集合失敗‘);
deferred.reject(errfind);
}
});
return deferred.promise;
}
/**
* 查詢數據集合 有條件
* @param collection
* @return 成功返回查詢到的數據集合內容,失敗返回-1
*/
function findCollectionHasCondition(collection,tmp){
collection.find(tmp).toArray(function(errfind,cols){
if(!errfind){
console.log(‘查詢數據集合成功‘+JSON.stringify(cols));
return JSON.stringify(cols);
}else {
console.log(‘查詢數據集合失敗‘);
return -1;
}
});
}
/**
* 刪除數據集合
* @param collection
* @param tmp
* @return 成功返回數據集合,失敗返回-1
*/
function removeCollection(collection,tmp){
//var tmp = {username:‘hello‘,password:1};
collection.remove(tmp,{safe:true},function(err, count){
if(err){
console.log(‘刪除數據集合失敗‘+tmp);
return -1;
}else {
console.log(‘刪除數據集合成功‘+count);
return collection;
}
});
}
裏面的關鍵點是:
- 定義defered對象
var deferred = Q.defer();
- 定義函數成功執行的resolve對象
deferred.resolve(JSON.stringify(cols));
- 定義函數成功失敗的error對象
deferred.reject(errfind);
- 最後返回一個新的promise對象,用來
return deferred.promise;
4.鏈式調用
user.openDatabase("localhost",27017,"test","users")
.then(function(data){
return user.openCollection(data[0],data[1])
})
.then(user.findCollectionNoCondition)
.done(function(data){
console.log(‘promise執行成功‘);
},function(err){
console.log("promise執行失敗:"+err);
});
5.log打印結果
GET / 304 55.922 ms - -
打開數據庫成功
連接數據集合成功
GET /stylesheets/style.css 304 6.048 ms - -
查詢數據集合成功[{"_id":"57731d3a239f75379769ce31","username":"liuchen","password":"12345"},{"_id":"577328ab5c8d6cf43b3e214d","username":"hello","password":1},{"_id":"577331f35c8d6cf43b3e214e","username":"hello","password":1},{"_id":"57733bf400a7090c35122844","username":"hello","password":1},{"_id":"57733c0300a7090c35122845","username":"hello","password":1},{"_id":"57733c0af8d7813443d51c27","username":"hello","password":1}]
promise執行成功
node.js對mongodb的連接&增刪改查(附async同步流程控制)