分页正确做法的分析

来源:互联网 发布:ps网络用语是什么意思 编辑:程序博客网 时间:2024/04/27 21:38

现有一data数据库,data里面student集合中信息如下:
这里写图片描述

集合中的文档信息很多,现我们希望通过用户向浏览器输入的url的page参数(即第几页)来想数据库中读取信息,每次读取10条信息
那现在我们有两种做法:
1)将所有的result都读取到数组中去,然后进行数据分页的操作
代码实现如下:

var express = require("express");var app = express();var db = require("./model/db.js");app.get("/",function (req,res) {    //url就是数据库的地址/表示数据库    //假如数据库不存在,没关系,程序会自动帮我们创建一个数据库    db.insertOne("student",{"name":"小胡","age":20},function (err,result) {        if(err){            console.log("插入数据失败");            return;        }        console.log("插入数据成功");        res.send("插入数据成功");    })})app.get("/find",function (req,res) {    //这个页面现在接受一个page 参数    //注意:这里面的Page是一个字符串,应该将它转化为数字,因为否则后面的就是字符串拼接    var page = parseInt(req.query.page); //express椎间盘没喝过读取get参数很简单    //调用find这个方法会自动连接数据库,内部调用了连接数据库的方法    db.find("student",{},function (err,result) {    //我们将数据库中student集合中所有的信息全部存储到result数组中去,然后根据page来从result中拿到对应数据        if(err){            console.log("数据查找失败");            return;        }        var a = [];        db.find("student",{},function (err,result) {            var totalpage = Math.ceil(result.length/10);             //判断用户所请求的页数有没有超过总共的页数            if(page >= totalpage){                page = totalpage-1;                for(var i = 10*page;i< result.length; i++) {                    //注意不能在这个地方将result[i]逐条发送出去,因为响应只能发送一次                    a.push(result[i]);                }                res.send(a);                return;            }            for(var i = 10*page;i< 10*(page+1); i++) {                //注意不能在这个地方将result[i]逐条发送出去,因为响应只能发送一次                a.push(result[i]);            }            res.send(a);        });        // res.writeHeader(200, {'Content-Type':'text/html;charset=UTF-8'})    })})app.listen(3000);

上面的做法显然不是最优化的,假想一盒用户只需要请求第三页的信息,然而我们这种做法确实将集合中所有的信息全部加载到数组中去,这样开销很大,这样显然不是最优化的方法。
在mongodb中提供了limit和skip的方法:
如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。
我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。
我们将连接数据库以及数据库的增删改查的方法封装为一个模块,向外暴露接口,提供函数

/这个模块里面封装了对所有数据库的常用操作//不管数据库的什么操作,都要先连接数据库,所以我们可以把连接数据库封装为一个函数var MongoClient = require("mongodb");var setting = require("../setting")//我们直接将数据库连接的函数封装起来,每次调用相关的函数,不用关系低层的代码//连接数据库function __connectDB(callback) {    //从setting文件中读取地址    var url = setting.dburl;    //连接数据库    MongoClient.connect(url,function (err,db) {        if(err){            console.log(err);            console.log("连接失败");            return;        }        console.log("连接成功了");        //当数据库连接成功之后调用回调函数做的事情        console.log(db);        callback(err,db);    })}//插入数据exports.insertMany = function (collectionName,array,callback) {    __connectDB(function (err,db) {        if(err){            callback(err,db);            db.close();            return;        }        db.collection(collectionName).insertMany(array,function (err,result) {          callback(err,result);          db.close();        })    })}//查找数据,找到所有的数据//用户可以不传args参数//由于JS函数没有重载的概念,也就是后面同名但是参数个数不同的函数会覆盖前面的函数exports.find = function (collectionName,json,C,D) {    var result = []; //结果将数组输出,不用多次调用回调函数  if(arguments.length == 3){      //当函数的参数为3时      //传进来的第三个参数即函数我们将其命名为回调函数      var callback = C;      //当不传入参数进入数组时,那么久默认取到集合中所有的数据      var skipnumber = 0;      var limit = 0;  }else if(arguments.length == 4){      var callback = D;      var args = C;      //应该省略的条数      var skipnumber = args.pageamout*args.page;      var limit = args.pageamout;  }else{      throw new Error("find函数的参数个数是三个或者四个");  }  // //表示我们要跳过的的个数  //   var skipnumber = args.pageamout*args.page;  // //表示我们需要查找的页数  //   var limit = args.pageamout;    console.log(skipnumber);    console.log(limit);    __connectDB(function (err,db) {        //当与数据库建立连接之后,开始查询数据        //使用游标遍历一个个文档        console.log(db);        var cursor = db.collection(collectionName).find(json).skip(skipnumber).limit(limit);        cursor.each(function (err,doc) {             if(doc != null){                 result.push(doc);             }else{                 //遍历文档结束,没有更多的文档了                 //给find方法里面传入回调函数,并将的到的文档数组传入回调函数中去                 callback(null,result);                 db.close();             }        })    })}//向外暴露删除exports.deleteMany = function (collectionName,json,callback) {    __connectDB(function (err,db) {        db.collection(collectionName).deleteMany(json,function (err,results) {            //表示删除数据之后应该做的事情                callback(err,results);                db.close();            })    })}//修改,json1为我们要查找的那个条件,json2表示那我们要修改为的那个json问题exports.updateMany = function (collectionName,json1,json2,callback) {    __connectDB(function (err,db) {        db.collection(collectionName).updateMany(json1, {$set: json2}, {$currentDate: { lastModified: true }} ,function (err,results) {            if(err){                console.log(err);                console.log("修改失败");                db.close();                return;            }           callback(err,results);            db.close();        })    })}
原创粉丝点击