前言
MongoDB越来越流行,NodeJS也越来越流行,也许你第一时间用上了KOA框架,但是如何才能在KOA用ES6的方式访问MongoDB呢?其实Github上不少类似的方案,比如你继续使用mongoose的Promise方式操作数据库,其实都没什么不可以。我的项目比较简单,不想用太多复杂的框架,自己写个Helper来连接数据库好了。
代码其实很简单,我贴出来,给官方驱动包个Promise壳儿,所有操作返回官方Promise,然后yield调用就这么简单
// helper_mongo.js文件
// 作者freewolf
// 当然还是使用官方驱动
var MongoClient = require('mongodb').MongoClient;
var ObjectID = require('mongodb').ObjectID;
var mongoLink = '';
// 这里修改成你的MongoLink字符串mongodb://user:password@yourserver
// 插入方法
var insert = function(collectionName, obj) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
collection.insert(obj, {w: 1}, function(err, res) {
db.close();
if (err) reject(err);
else resolve(res[0]);
});
});
});
}
// 更新
var update = function(collectionName, obj) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
collection.update({_id: new ObjectID(obj._id)}, obj, {upsert: true,w: 1}, function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
});
});
}
// 查找一个
var findOne = function (collectionName, query, option) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
if(option==undefined || option==null)
{
collection.findOne(query, function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
}else{
collection.findOne(query, option, function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
}
});
});
}
// 查找多个
var find = function(collectionName, query, option) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
if(option==undefined || option==null)
{
collection.find(query).toArray(function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
}else{
collection.find(query, option).toArray(function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
}
});
});
}
// 删除
var remove = function(collectionName, query) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
collection.remove(query, {w: 1}, function(err, res) {
db.close();
if (err) reject(err);
else resolve(res);
});
});
});
}
// 计数
var count = function(collectionName, query, option) {
return new Promise(function(resolve, reject) {
MongoClient.connect(mongoLink, function(err, db) {
if (err) reject(err);
var collection = db.collection(collectionName);
if(query==undefined || query==null)
query = {};
if(option==undefined || option==null)
{
collection.count(query, function(err, count) {
db.close();
if (err) reject(err);
else resolve(count);
});
}else{
collection.count(query, option, function(err, count) {
db.close();
if (err) reject(err);
else resolve(count);
});
}
});
});
}
module.exports.insert = insert;
module.exports.update = update;
module.exports.findOne = findOne;
module.exports.find = find;
module.exports.remove = remove;
module.exports.count = count;
好了 Helper结束
怎么使用呢?
使用一个Service来装饰一下
// service.js文件
var ObjectID = require('mongodb').ObjectID;
var helperMongo = require('./helper_mongo');
module.exports = {
// 创建
insert : function * (obj){
var res = yield helperMongo.insert(this.collectionName, obj);
return res;
},
// 更新
update : function * (obj){
var res = yield helperMongo.update(this.collectionName, obj);
return res;
},
// 删除
remove : function * (id){
var res = yield helperMongo.remove(this.collectionName, { _id : new ObjectID(id) });
return res;
},
// 查询
find : function * (query, option){
var res = yield helperMongo.find(this.collectionName, query, option);
return res;
},
// 查询
findOne : function * (query, option){
var res = yield helperMongo.findOne(this.collectionName, query, option);
return res;
},
// 取全部
getAll : function * (){
var res = yield helperMongo.find(this.collectionName, {});
return res;
},
// 按照id查询
getById : function * (id){
var res = yield helperMongo.findOne(this.collectionName, { _id : new ObjectID(id) });
return res;
},
// 按照很多id来查询
getByIds :function * (ids, option){
ids = ids.map(function(id) { return new ObjectID(id); });
var res = yield helperMongo.find(this.collectionName, {_id: {$in: ids}}, option);
return res;
},
// 列出(带分页)
getByPage : function*(query, sort, pageSize, pageNum){
if(!query)
query = {};
if(!sort)
sort = [['_id', 'desc']];
var option = {
sort : sort,
limit: pageSize,
skip : (pageNum - 1) * pageSize
};
var res = yield helperMongo.find(this.collectionName, query, option);
return res;
},
// 计数
count : function * (query){
if(!query)
query = {};
var res = yield helperMongo.count(this.collectionName, query);
return res;
}
}
然后呢?
其实更简单 单例的操作从service继承
// service_user.js举例
var service = require('./service');
var helperMongo = require('../helper_mongo');
var ObjectID = require('mongodb').ObjectID;
var Service = function(){
this.collectionName = 'users';
// 这里扩充你自己的方法 比如 按照邀请码搜索
this.getByInviteCode = function * (inviteCode){
var res = yield this.findOne({ invitecode : inviteCode });
return res;
}
if(Service.instance == null)
{
Service.instance = this;
}
return Service.instance;
}
Service.prototype = service;
module.exports = Service;
好了 再看如何使用
var co = require('co');
var ServiceUser = require('./service_user.js');
var serviceUser = new ServiceUser();
// 其实可以直接返回单例实例在service_user.js 但是WS不能出提示 还是这样吧
// Demo下
co(function*(){
var user = {name:'freewolf', password:'123', invitecode:'abcd'};
// 插入
yield serviceUser.insert(user);
// 查找 使用service包装的方法
var user1 = yield serviceUser.find({name:'freewolf'});
// 查找 使用扩展方法
var user2 = yield serviceUser.getByInviteCode('abcd');
// 分页
var sort = [['lastedittime', 'desc']];
var pageSize = 20; // 每页20条
var pageNum = 1; // 第一页
var users = yield serviceUser.getByPage({}, sort, pageSize, pageNum);
// ......
});
就写这么多吧,这个玩意就是官方驱动包个壳,很好用,满足一般的需求。其实JS我并不太擅长,有什么语法怪怪的地方,欢迎大家拍砖~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。