nodejs mysql mvc_一种nodejs的MVC框架

mvc会针对请求进行分发,分发一般有controller(针对模块),action(针对模块中的方法),args(请求的参数)。

1.先对http请求的url进行设置,解析url中的各种参数:

//config.js

var route = require('./route');

//针对ajax请求

route.map({

method:'get',

url:/^\/category/mailCategory/i,

controller:'mailCategory',

action:'getMailCategory'});

//controller为空,针对页面,针对页面

route.map({

method:'get',

url:/^\/$/i,

controller:'',

action:'list.html'});

server.js的入口:

exports.runServer = function(port){

port= port || 10088;/*function(req,res){}它将会自动加入到 'request' 事件的监听队列。

它是http.IncomingMessage的一个实例。*/

var server = http.createServer(function(req, res){var _postData = '';//on用于添加一个监听函数到一个特定的事件

req.on('data', function(chunk)

{

_postData+=chunk;

})

.on('end', function()

{

req.post=querystring.parse(_postData);

handlerRequest(req, res);

});

}).listen(port); //程序运行的入口

console.log('Server running at http://180.150.189.25:'+ 10088 +'/');

};

当接收完请求的URL之后,执行handlerRequest(req, res);

/**

* 所有请求的统一入口*/

var handlerRequest = function(req, res){//通过route来获取controller和action信息

var actionInfo =route.getActionInfo(req.url, req.method);//如果route中有匹配的action,则分发给对应的action

if(actionInfo.action){var controller =actionInfo.controller;//直接跳转页面

if(controller == ""){

viewEngine.forward(req, res, actionInfo.action);return;

}//加载action

if(controller[actionInfo.action]){var ct = newcontrollerContext(req, res);//如果是post请求,从重新设置参数

if(req.method.toLowerCase() == "post"){

actionInfo.args=req.post;

}//通过apply将controller的上下文对象传递给action,路径转化就在这里。

controller[actionInfo.action].call(ct, actionInfo.args);

}else{

handler500(req, res,'Error: controller "' + actionInfo.controller + '" without action "' + actionInfo.action + '"')

}

}else{//如果route没有匹配到,则当作静态文件处理

staticFileServer(req, res);

}

};

viewEngine.forward代码如下:

var staticFileServer = function(req, res, filePath){if(!filePath){

filePath=path.join(__dirname, config.staticFileDir, url.parse(req.url).pathname);

}

fs.exists(filePath,function(exists) {if(!exists) {//目录不存在的情况

handler404(req, res);return;

}var raw =fs.createReadStream(filePath);var ext =path.extname(filePath);

ext= ext ? ext.slice(1) : 'html';var acceptEncoding = req.headers['accept-encoding'];var head = {'Content-Type': contentTypes[ext] || 'text/html'};if (!acceptEncoding) {

acceptEncoding= '';

}//根据请求头部信息,返回相应的数据

if(acceptEncoding.match(/\bgzip\b/)) {

head["content-encoding"] = "gzip";

res.writeHead(200, head);

raw.pipe(zlib.createGzip()).pipe(res);

}else if (acceptEncoding.match(/\bdeflate\b/)) {

head["content-encoding"] = "deflate";

res.writeHead(200, head);

raw.pipe(zlib.createDeflate()).pipe(res);

}else{

res.writeHead(200, head);

raw.pipe(res);

}

});

};

ct的上下文如下:

//controller的上下文对象

var controllerContext = function(req, res){this.req =req;this.res =res;this.dbPool =dbPool;this.contextPath =__dirname;this.handler404 =handler404;this.handler500 =handler500;

};

2.controller

通过上面的转发就可以把URL与module中的方法映射起来,我们写方法就可以按照模块来写了,例如mailCategory中的getMailCategory的方法如下:

在src模块中的action模块的MailCategory.js中:

/*MailCategory.js,提供两个action

getMailList 和 getMailCategory*/exports.getMailList= function(args){var context = this;var result = {errCode: 0, msg: 'success', categoryId: categoryId, data:[]};//参数校验

var categoryId =args.categoryId;if(!categoryId){

emitter.emit("invalidCategoryId", result, context);return false;

}/**

* 获取邮件栏目信息

* @param isList 1 只是返回栏目列表 0 返回栏目及模块信息

* @returns {errCode:0, msg:'success', data:[{id:'', name: '', alias: ''},...]}

* @returns {errCode:0, msg:'success', data: [{id:'', name:'', alias:'', modules:[{id:'', name:''}, ...]}]}*/exports.getMailCategory= function(args){

}

3.module

为controller层提供数据,直接与数据库连接,或者中间加一道缓存,例如redis。刚刚看到在映射的过程中,传递对象的成员

this.dbPool =dbPool;

它的定义如下:

dbManager = require('./src/utilities/DbManager');//数据库链接池

var dbPool = dbManager.getPool();

DbManager.js封装了连接数据库,或者一个连接池的对象

//创建mysql数据库链接

var mysql = require('mysql');//连接池

var dbConfig ={

host:'180.150.189.25',

port:'3306',

user:'iyy',

password:'iyy@2015',

database:'anthony',

connectionLimit:20 //连接池最大连接数

//waitForConnections: false

}//从数据库获取一个链接

exports.getConnection = function(){returnmysql.createConnection(dbConfig);

}

exports.getPool= function(){var pool =mysql.createPool(dbConfig);returnpool;

}

这样就可以在controller模块中直接操作数据库,如下:

context.dbPool.getConnection(function(err,connection){if(err){

emitter.emit("connectFailed", result, context);return false;

}//可以进一步拆分到module中。

connection.query("delete from MailModule where id="+intDeleteId,function(err,res){if(err) {

emitter.emit("queryFailed", result, context);return false;

}/*emitter.on("success", function(result, context){

result.errCode = 0;

result.msg = "success";

var str='updateuserinfo_callback({"ret":2,"errmsg":"asdas"})';

context.renderJson(str);

});*/emitter.emit("success", result, context);

});//释放链接

connection.end();

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值