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執行成功