寫法上還是模塊化,盡量把不同職責的代碼分開,避免"萬能類",盡量采用MVC。
連接,創建數據庫,插入數據
db.js:
//這個模塊里面封裝了所有對數據庫的常用操作
var MongoClient = require('mongodb').MongoClient;
//不管數據庫什么操作,都是先連接數據庫,所以我們可以把連接數據庫
//封裝成為函數
function _connectDB(callback) { var url = "MongoDB://127.0.0.1/haha"; MongoClient.connect(url, function (err,db) { if(err) { callback(err,null); return; } callback(err,db); }); } exports.insertOne = function (collectionName, json, callback) { _connectDB(function (err,db) { if(err) { callback(err,null); return; } db.collection(collectionName).insertOne(json, function (err, result) { callback(err, result); db.close();//關閉數據庫 }) }); } exports.find = function (collectionName,json,callback) { var result = []; //結果數組 if(arguments.length != 3) { callback("find函數接受三個參數",null); return ; } //鏈接數據庫,鏈接之后查找所有 _connectDB(function (err,db) { var cursor = db.collection(collectionName).find(json); cursor.each(function (err, doc) { if(err) { callback(err,null); return; } if(doc != null) { result.push(doc); //放入結果數組 }else { //遍歷結束,沒有更多的文檔 callback(null,result); } }); }); }
01.js:
var express = require("express");
var app = express(); var MongoClient = require('mongodb').MongoClient; app.get("/",function (req,res) { //url就是數據庫地址,/表示數據庫 //假如數據庫不存在,沒有關系,程序會幫你自動創建一個數據庫 var url = "mongodb://localhost:27017/haha"; //連接數據庫 MongoClient.connect(url, function(err, db) { //回調函數表示鏈接成功做的事情,db參數就是連接上的數據庫實體 if(err) { console.log("數據庫連接失敗"); return ; } console.log("連接數據庫成功"); //插入數據,集合如果不存在,也沒有關系,程序會幫你創建 db.collection("student").insertOne({ "name" : "哈哈", "age" : parseInt(Math.random()*100 + 10) }, function(err, result) { if(err) { console.log("插入失敗"); return ; } console.log("插入成功"); console.log(result); res.send(result); db.close(); }); db.close(); }); }); app.listen(3000);
1版本分頁
在db.js這種版本的分頁效率是比較低的,因為已經查詢了所有數據庫,然后篩選需要push進數組。
02.js:
var express = require("express");
var app = express(); var db = require("./model/db.js"); app.get("/",function (req,res) { db.insertOne("teacher",{"name":"小紅"},function (err,result) { if(err) { console.log("插入失敗"); } res.send("插入成功"); }); }); app.get("/du",function (req, res) { //這個頁面現在接受一個page參數。 var page = parseInt(req.query.page); //express中讀取get參數很簡單 var a = []; db.find("student",{},function (err,result) { //這是一種分頁查詢的笨方法,效率低,因為已經查詢了所有數據庫,然后再回調里面篩選 for(var i = 10 * page; i < 10*(page + 1); i++ ) { a.push(result[i]); } res.send(a); }); }); app.listen(3000);
2版本分頁
利用mongodb自帶的函數limit()和skip(),重寫db2.js,實現分頁,但是這兩個函數底層是怎么實現的呢,據說效率蠻高,底層實現這里暫時先不探究,日后專門開一篇來探討。
//優化后,加入skip,limit參數的寫法 //這個模塊里面封裝了所有對數據庫的常用操作 var MongoClient = require('mongodb').MongoClient; //不管數據庫什么操作,都是先連接數據庫,所以我們可以把連接數據庫 //封裝成為函數 function _connectDB(callback) { var url = "MongoDB://127.0.0.1/haha"; MongoClient.connect(url, function (err,db) { if(err) { callback(err,null); return; } callback(err,db); }); } exports.insertOne = function (collectionName, json, callback) { _connectDB(function (err,db) { if(err) { callback(err,null); return; } db.collection(collectionName).insertOne(json, function (err, result) { callback(err, result); db.close();//關閉數據庫 }) }); } exports.find = function (collectionName,json,C,D) { var result = []; //結果數組 //JS沒有函數重載,只能手動實現 if(arguments.length == 3) { //如果沒有傳args //那么參數C就是callback,參數D沒有傳。 var callback = C; var skipnumber = 0; //數目限制,limit(0)就是沒有限制 var limit = 0; }else if(arguments.length == 4) { var args = C; var callback = D; //應該省略的條數 var skipnumber = args.pageamount * args.page; //數目限制 var limit = args.pageamount; }else { throw new Error("find函數的參數個數,必須是3個,或者4個"); return; } //從第零頁開始 console.log("略過了"+skipnumber+"條"+"限制在"+limit+"條"); //鏈接數據庫,鏈接之后查找所有 _connectDB(function (err,db) { var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit); cursor.each(function (err, doc) { if(err) { callback(err,null); return; } if(doc != null) { result.push(doc); //放入結果數組 }else { //遍歷結束,沒有更多的文檔 callback(null,result); } }); }); }
03.js:
//limit,skip高效率做法 var express = require("express"); var app = express(); var db = require("./model/db2.js"); app.get("/",function (req,res) { db.insertOne("teacher",{"name":"小紅"},function (err,result) { if(err) { console.log("插入失敗"); } res.send("插入成功"); }); }); app.get("/du",function (req, res) { //這個頁面現在接受一個page參數。 var page = parseInt(req.query.page); //express中讀取get參數很簡單 //每頁10個,查第三頁 // db.find("student",{},{"pageamount":5,"page":page},function (err,result) { // db.find("student",{},function (err,result) { //注意這個結果還是5條,是先find在age大於50情況的結果集里面skip和limit db.find("student",{"age":{$gt:50}},{"pageamount":5,"page":page},function (err,result) { if(err) { console.log(err); } res.send(result); }); }); app.listen(3000);
因為原生js沒有函數重載,注意這里還手動對函數根據參數個數不同進行了重載,盡量讓程序健壯。注釋很詳細了。