node.js对mongodb的连接&增删改查(附async同步流程控制)


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

















免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM