用“MEAN”技术栈开发web应用(三)用mongodb搭建数据库

javawangli 8年前

来自: http://www.cnblogs.com/lvdabao/p/mean-techstack-mongodb.html

上一篇介绍了如何用express搭建起服务端MVC的开发架构,本篇我们来详细介绍一下这个Model层,也就是数据库访问层。包含如何使用mongodb搭建数据库,以及如何使用mongoose来访问数据。

mongodb的安装和启动

首先我们得安装mongodb,先去官网(  http://www.mongodb.org/downloads )下载安装包,我的开发环境是Windows,所以下载Windows下的iso文件,根据提示一路安装完毕即可,没什么需要特别选择的。

安装完后,为了能在cmd中全局都能启动mongodb,我们需要配置环境变量,将安装目录下的bin目录配置在系统变量中,如图:

接下来,新建一个目录,用于存放数据库文件。我新建的目录为D:\mongodb\data\db,然后运行cmd,执行命令mongod --dbpath D:\mongodb\data\db,这个时候mongodb就运行起来了,我们就可以用程序来连接数据库了。

连接数据库

mongodb的默认端口是27017,我们在项目中有一个models文件夹,里面放置与数据库连接的数据模型,其中有一个mongodb.js,内容很简单:

var mongoose = require('mongoose');  mongoose.connect('mongodb://localhost/QuestionMaker');  exports.mongoose = mongoose;

是标准的commonjs模块写法,先引用mongoose模块,然后连接数据库,对外暴露mongoose模块。可以看到我们在代码中去访问本地的QuestionMaker数据库。那么首先我们得有这个数据库才行。运行cmd,创建一个数据库

use QuestionMaker

db.createCollection("counters")

此命令会创建一个名为QuestionMaker的数据库,并在该库创建一个集合counters(这个集合我们后续会用到),必须得这么写,否则数据库无法创建。驱动模块写好了,我们在其他模块中引用该模块后,就可以连接到数据库了。

使用mongoose操作数据库

我们看到上面用了一个叫做mongoose的模块,它是一个nodejs模块,mongoose提供了Schema、Model、Documents对象,用它可以更加直观的操作数据库,所以很多人喜欢这个模块,我们项目中也用它来操作数据库。

为了能以我们熟悉的面向对象的方式来访问数据库,我们先根据试题的数据结构来创建一个Schema:

var QuestionSchema = new Schema({       id: String,      qtype: Number,      name: String,      content: String,      options: [          {              name: String          }      ],      answer: String  });

Schema可以理解为一个模板,根据此模版,我们可以用mongoose.model来创建出一个Question类,代码如下:

var Question = mongodb.mongoose.model("Question", QuestionSchema);

利用Question类示例化出的对象带有很多方法用来访问/操作数据库,如save方法,可以保存一条文档,也就是document(mongodb中的概念,类似我们以前概念中的一条记录)。

为了尽可能少的对外暴露数据(封装性),我新建了一个QuestionDAO对象,也就是仿造java中的概念,加一个DAO层,用来提供数据访问。对外暴露的方法都定义在这个对象上,例如保存记录和更新记录的代码如下:

//保存试题  QuestionDAO.prototype.save = function(obj, callback){       var instance = new Question(obj);       instance.save(function(err){            callback(err, null);       });  }    //更新试题  QuestionDAO.prototype.update = function(obj, callback){       Question.findByIdAndUpdate(obj._id, obj, {}, function(err){            callback(err, null);       });  }

用了mongoose提供的save方法和findByIdAndUpdate方法,每一个操作之后都可以传回调函数,这样我们就能把数据库访问的结果返回给controller层了。

另外,根据业务需求,我们就可以写更多的方法了,如项目中的list、get、remove,分别用来获取试题列表、获取试题、删除试题。其中list方法中还实现了分页返回数据。

mongodb实现id自增

id自增是数据库的一个常见需求,在mysql中,只要指定字段auto_increment即可,在mongodb中,没有这样的方法,所以必须得在代码中实现才行。我们按照官方给出的解决方法,实现questions集合的id自增。

id自增功能需要一个辅助的集合来完成,就是我们之前新建好的counters,用来记录当前的id值为多少。在mongodb命令行中执行db.counters.save({_id: "questionid", seq: 0})完成初始化。_id是mongodb默认提供的一个字段,我们这里赋值为questionid,是为了做一个标记,以便在后面能够查找出这条记录。

然后在question.js中创建CounterSchema并生成一个Counter类,用来操作counters集合,代码如下:

然后,在QuestionSchema的save方法之前,我们应该先去counters中获取最新id,可以用pre方法来实现,代码如下:

如此一来,每次Question执行save方法的时候,都会调用这个函数,从而获取到递增后的最新id。

备份和导入

数据库的备份和导入当然是必不可少了,比如大家可以拿这我的备份文件直接导入来练习,这样就省去了一步一步创建的步骤。

备份数据库可以使用mongodump命令,用法如下:

mongodump -h dbhost -d dbname -o dbdirectory

导入已有的数据库可以使用mongostore命令,用法如下:

mongorestore -h dbhost -d dbname –directoryperdb dbdirectory

具体的参数可以在网上搜索,文章很多,此处不再详细说明。

客户端工具

mongodb有没有像mysql那样的客户端工具呢?当然有啦,我使用的是robomongo这个工具,简单好用,界面如下,大家可以尝试使用。

使用MEAN技术栈开发web应用系列三部曲就到这里了,再次附上练手项目的地址: https://github.com/Double-Lv/QuestionMaker

另外,本系列文章只是一个入门级别的介绍,所写的代码以及数据库的设计基本上都属于”玩具代码“,写一个自己玩的项目还行。在实际的项目中,我们还得考虑各种因素,性能、负载等等,更多话题有待研究。

</div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div>

posted @ 2016-02-01 23:56 吕大豹 阅读( ... ) 评论( ... ) 编辑 收藏

</div>