踏上nodejs的不归路——03阶段性胜利
今天我就继续咱们的nodejs之旅,上次说到了,做项目之前的各种准备,包括最主要的express框架,velocity模板引擎依赖包,mongodb的依赖包,还有一些其他的依赖包,并且修改express所用的模板引擎,让express全面支持velocity模板引擎,这样我们就有了一个系统的架子,下一步我们就开始往架子上添砖加瓦——做一个最简单的增删改查的例子,对了在此之前我先简单介绍一下mongodb吧,mongodb是一种介于关系型数据库与菲关系型数据库之间的一种轻量级数据库,与我们通常使用的关系型数据库相比,操作简单(非常爽),免费,即下即用,广泛应应用于软件行业,大大降低了运营成本,下载安装详见官网http://www.mongodb.org/,下载后可以把mongodb加入到系统启动项中,可以轻松可视化手动启动,也可以用命令行窗口进入到安装bin目录执行mongod命令启动服务,具体的详细命令请参考http://www.iteye.com/topic/757301,里面写的非常详细,一般把增删改查弄会就可以了,非常简单类类似于使用方法,下面就进入正题——做一个增删改查的例子。
这是项目的总体文件夹分配
第一步,我们设计好路由控制器
总体想一下我们要有几个操作,跳转到list页面,跳转到添加页面,进行添加操作,跳转到修改页面,进行修改操作,点击删除按钮进行删除操作,所以我们大致可以设计这样几个路由控制的路径,其中跳转到修改页面和删除操作需要传参数。代码如下
//列表显示 app.get('/list',routes.list); //跳转到编辑页面 app.get('/edit/:_id',routes.toEdit); //编辑 app.post('/edit',routes.edit); //跳转到添加页面 app.get('/save',routes.toSave); //进行添加操作 app.post('/save',routes.save); //删除操作 app.get('/delete/:id',routes.del);
大家发没发现有get和post两种形式,这与java的get和post请求应该是一样的,app.get('',function(req,res){}),get和post方法用于接收用户提交的请求地址,有两个参数,第一个是用户请求的地址,后面是一个回调函数,回调函数里有两个参数req(request)和res(response),用于处理用户请求并发送服务器响应到客户端,也就是浏览器,这个过程就是express最大的特点——路由控制器。
第二步,设置数据库设置文件以及数据库util文件,我就简单说一下,直接见代码。
setting.js文件,直接放在根目录下就可以
/** * Created with JetBrains WebStorm. * User: Administrator * Date: 12-9-25 * Time: 上午9:58 * To change this template use File | Settings | File Templates. */ module.exports={ cookieSecret:"myTest", db:"myTest", host:"localhost" }
models文件夹下的db.js文件
/** *创建数据库连接 * 该模块只会被加载一次,一直使用相同的实例 */ //引入连接配置的模块 var settings=require("../settings"); //得到db对象 var Db=require("mongodb").Db; //得到连接对象 var Connection=require("mongodb").Connection; //得到服务对象 var Server=require("mongodb").Server; //创建连接对象并暴漏给你接口 module.exports=new Db(settings.db,new Server(settings.host,Connection.DEFAULT_PORT,{}));
第三步,我们就开始编写实体和dao,这里说的实体和dao只是一个比喻,也就是说下面写的东西类似于java web工程中的实体类和dao,我把他们放在一个文件里了,大家可以将这两个东西分开,首先先引入上一步编写的数据库类。
var mongodb = require('./db');
这里还要补充一下mongdb的知识,mongodb中在往表格里插入数据时,会自动生成一个_id的列,最开始的时候我还以为这是一个字符串,但是在后面的操作中遇到了困难,在velocity中,这个字段的确会被解析成一个字符串,但是在数据库表中,它是一个特殊对象,是一个object,所以再进行跳转到编辑页面,和删除操作的时候,就遇到了一个困难,如何将一个字符串转换成对象类型,我查遍了网上,就在山重水复疑无路的时候,我看到了柳暗花明又一村,只要引入下面的模块
var BSON = require('mongodb').BSONPure;
然后调用一个方法,把从velocity中解析出来的字符串_id作为参数传进去,就可以构造一个这样类型的对象
BSON.ObjectID.createFromHexString(_id)
然后在这个类里面写一个方法,有点类似于java中的构造器。
function User(user){ this._id = user._id; this.username = user.username; this.age = user.age; }
下面我就介绍一个我写的dao里的一个方法吧(其他方法类似),findById,通过id查找记录,首先要说明一下,我在这里使用类似于静态方法的一种写法User.findById = function(callback){},这里面传的参数是一个回调函数,如果想调用非静态方法,只需在中间加上一个prototype就可以了,这样只能创建这个对象实例后才能调用这个方法,这个回调函数非常重要,什么错误信息啊,查询的记录啊,都是以回调函数的方式返回的,首先打开mongodb输入输出流,为什么叫输入输出流呢,这是我发明的,我觉得就是一个流,因为mongodb是往文件里面直接写东西,最后一定记得关哦(越来越像java中的流)
mongodb.open(function(err,db){})//里面的参数err是错误信息,db是连接的数据库信息
之后调用db的collection方法(这里说明一下,mongodb里的表叫collection),这样就能对数据库表格进行操作了
db.collection("user",function(err,collection){});//collection即表格对象
这样就可以对表格进行操作了,调用collection对象的findOne方法,传入参数,然后有一个回调函数,里面的参数doc就是返回的一个json格式的对象,然后把返回的对象放到总的回调函数里,这样如果调用此方法后,就会返回这个回调函数。
collection.findOne({_id:BSON.ObjectID.createFromHexString(_id)},function(err,doc){ mongodb.close(); if(doc){ var user = new User(doc); callback(null,user); }else{ callback(err,null); } });
总体的代码如下,请您细细品尝
User.findById = function(_id,callback){ mongodb.open(function(err,db){ if(err){ return callback(err); } db.collection("user",function(err,collection){ if(err){ mongodb.close(); return callback(err); } //console.log(_id); collection.findOne({_id:BSON.ObjectID.createFromHexString(_id)},function(err,doc){ mongodb.close(); if(doc){ var user = new User(doc); callback(null,user); }else{ callback(err,null); } }); }); }); }
其他的方法于此类似,代码我会以附件形式传给大家。
第四步,编写路由控制的方法,第一步我在app.js文件里定义了路由控制器,我说过,里面的第二个参数是个回调函数,所以express里面把这些方法全部统一定义在routes文件夹下的index.js文件里,这里面都是一些对外共享的方法,
exports.list = function(req, res){ User.findAll(function(err,userlist){ res.render('list',{title:'员工列表',users:userlist}); }); }
这里面调用了dao中的方法,调用方法时如果有参数要传入该方法,应该在回调函数之前将参数加入并用逗号与回调函数隔开,代码如下
User.findById(req.params._id,function(err,user){ res.render('edit',{title:'编辑',user:user}); });
还要说一下,如果用户是get请求,那么请求参数是放在请求路径里,所以获得请求参数的方法是req.params.参数名,如果是post请求(提交表单),那么请求参数获取方式为req.body.参数名。velocity页面中如何呈现,我就不细说了,网上有velocity的教程,了解一些简单的用法就行了,好了这个增删改查的例子就到这里了,讲的有点乱,不过思路还是清晰的,把我遇到的问题基本上都和大家分享了,希望能为大家打开nodejs开发旅程的大门。附件里有我的代码,大家有时间可以研读一下,有什么问题,意见,建议都可以给我留言,页面我用的bootstrap前端框架,因为是练习的项目,所以做的有点草,格式有点问题,希望大家见谅。