-
Notifications
You must be signed in to change notification settings - Fork 110
web mvc todo chinese
fantasyni edited this page May 3, 2014
·
1 revision
Node 非常擅长进行web应用开发, 通过使用Bearcat Node web 开发会变得更加容易, 快速和可维护.
让我们开始Bearcat实战系列教程 -- web mvc todo
你可以先可以参照todo的说明尝试着把todo应用简单的跑起来
跑起来后大致是这样的
你可以添加, 更新, 完成, 删除你的todo列表
这个todo应用数据库用的是mysql, 因此, 首先我们要确定好sql表结构
DROP TABLE IF EXISTS `bearcat_todo`;
CREATE TABLE `bearcat_todo` (
`id` bigint(20) NOT NULL,
`title` varchar(300) default NULL,
`finished` int(11) default 0,
`post_date` bigint(20) default 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
为了使用 Bearcat-dao 提供的 O/R mapping, 我们需要添加如下的IDGenerator表用于生成表bearcat_todo唯一的主键id
create table IDGenerator(
name varchar(50) NOT NULL,
id bigint(20) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (name)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into IDGenerator (name, id) values ('bearcat_todo', 0);
添加 bearcat 和 bearcat-dao 依赖到 package.json
"bearcat": "~0.1.0",
"bearcat-dao": "~0.1.0"
添加context.json文件, 使用占位符来根据不同的环境来配置不同的值
{
"name": "bearcat-todo",
"dependencies": {
"bearcat-dao": "*"
},
"scan": "app",
"beans": [{
"id": "mysqlConnectionManager",
"func": "node_modules.bearcat-dao.lib.connection.sql.mysqlConnectionManager",
"props": [{
"name": "port",
"value": "${mysql.port}"
}, {
"name": "host",
"value": "${mysql.host}"
}, {
"name": "user",
"value": "${mysql.user}"
}, {
"name": "password",
"value": "${mysql.password}"
}, {
"name": "database",
"value": "${mysql.database}"
}]
}]
}
我们现在要编写我们的O/R mapping domain 对象, 它是一个简单的POJO, 没什么特别的
var TodoDomain = function() {
this.id = null;
this.title = null;
this.finished = 0;
this.post_date = 0;
}
module.exports = {
func: TodoDomain,
primary: [{
name: "id",
type: "Long"
}],
fields: ["title", "finished", "post_date"],
tableName: "bearcat_todo"
}
之后我们编写todoDao来添加对表bearcat_todo的CRUD增删改查操作
todoDao 也是一个简单的由Bearcat IoC 容器所管理的POJO
var TodoDomain = require('../domain/todoDomain');
var TodoDao = function() {
this.domainDaoSupport = null;
}
TodoDao.prototype.setDomainDaoSupport = function(domainDaoSupport) {
this.domainDaoSupport = domainDaoSupport;
}
TodoDao.prototype.getDomainDaoSupport = function() {
return this.domainDaoSupport;
}
TodoDao.prototype.init = function() {
// init todoDao with todoDomain to specify the O/R mapping domain for current todoDao
this.domainDaoSupport.initConfig(TodoDomain);
}
TodoDao.prototype.getList = function(params, cb) {
var sql = ' 1=1 order by finished asc, id asc limit ?,?';
return this.domainDaoSupport.getListByWhere(sql, params, null, cb);
}
TodoDao.prototype.addTodo = function(params, cb) {
var sql = 'insert into ' + this.domainDaoSupport.getTableConfig().getTableName() + ' set title = ?, post_date = ?';
return this.domainDaoSupport.add(sql, params, cb);
}
TodoDao.prototype.getTodoById = function(id, cb) {
return this.domainDaoSupport.getById(id, cb);
}
TodoDao.prototype.updateTodo = function(title, id, cb) {
var sql = 'update ' + this.domainDaoSupport.getTableConfig().getTableName() + ' set title = ? where id = ?';
return this.domainDaoSupport.update(sql, [title, id], cb);
}
TodoDao.prototype.updateTodoFinished = function(finished, id, cb) {
var sql = 'update ' + this.domainDaoSupport.getTableConfig().getTableName() + ' set finished = ? where id = ?';
return this.domainDaoSupport.update(sql, [finished, id], cb);
}
TodoDao.prototype.deleteById = function(id, cb) {
return this.domainDaoSupport.deleteById(id, cb);
}
module.exports = {
id: "todoDao",
func: TodoDao,
props: [{
name: "domainDaoSupport",
ref: "domainDaoSupport"
}],
"init": "init"
}
Service 层基于 Dao 层, 并且被Controller层所调用
var TodoService = function() {
this.todoDao = null;
}
TodoService.prototype.getList = function(params, cb) {
return this.todoDao.getList(params, cb);
}
TodoService.prototype.addTodo = function(params, cb) {
return this.todoDao.addTodo(params, cb);
}
TodoService.prototype.getTodoById = function(id, cb) {
return this.todoDao.getTodoById(id, cb);
}
TodoService.prototype.updateTodo = function(title, id, cb) {
return this.todoDao.updateTodo(title, id, cb);
}
TodoService.prototype.updateTodoFinished = function(finished, id, cb) {
return this.todoDao.updateTodoFinished(finished, id, cb);
}
TodoService.prototype.deleteById = function(id, cb) {
return this.todoDao.deleteById(id, cb);
}
module.exports = {
id: "todoService",
func: TodoService,
props: [{
name: "todoDao",
ref: "todoDao"
}]
}
Controller 在web中就是处理request, response请求的那层
var TodoController = function() {
this.todoService = null;
}
// get index list
TodoController.prototype.index = function(req, res, next) {
this.todoService.getList([0, 50], function(err, results) {
if (err) {
console.log(err);
return;
}
res.render('index.html', {
todos: results
});
});
}
// create a new todo list
TodoController.prototype.new = function(req, res, next) {
var title = req.body.title || '';
title = title.trim();
if (!title) {
return res.render('error.html', {
message: '标题是必须的'
});
}
this.todoService.addTodo([title, Date.now()], function(err, result) {
if (err) {
return next(err);
}
res.redirect('/');
})
}
TodoController.prototype.view = function(req, res, next) {
res.redirect('/');
}
// edit a todo list
TodoController.prototype.edit = function(req, res, next) {
var id = req.params.id;
this.todoService.getTodoById(id, function(err, result) {
if (err) {
return next(err);
}
if (!result) {
return next();
}
result = result[0];
res.render('todo/edit.html', {
todo: result
});
});
}
// save a todo list
TodoController.prototype.save = function(req, res, next) {
var id = req.params.id;
var title = req.body.title || '';
title = title.trim();
if (!title) {
return res.render('error.html', {
message: '标题是必须的'
});
}
this.todoService.updateTodo(title, id, function(err, result) {
if (err) {
return next(err);
}
res.redirect('/');
});
}
// delete a todo list
TodoController.prototype.delete = function(req, res, next) {
var id = req.params.id;
this.todoService.deleteById(id, function(err, result) {
if (err) {
return next(err);
}
res.redirect('/');
});
}
// finish a todo list
TodoController.prototype.finish = function(req, res, next) {
var finished = req.query.status === 'yes' ? 1 : 0;
var id = req.params.id;
this.todoService.updateTodoFinished(finished, id, function(err, result) {
if (err) {
return next(err);
}
res.redirect('/');
});
}
module.exports = {
id: "todoController",
func: TodoController,
props: [{
name: "todoService",
ref: "todoService"
}]
}
启动Bearcat, 添加route配置给connect, express之类的web框架
var contextPath = require.resolve('./context.json');
var bearcat = Bearcat.createApp([contextPath]);
bearcat.start(function() {
/**
* Routing
*/
var router = urlrouter(function(app) {
app.get('/', bearcat.getRoute("todoController", "index"));
app.post('/todo/new', bearcat.getRoute("todoController", "new"));
app.get('/todo/:id', bearcat.getRoute("todoController", "view"));
app.get('/todo/:id/edit', bearcat.getRoute("todoController", "edit"));
app.post('/todo/:id/edit', bearcat.getRoute("todoController", "save"));
app.get('/todo/:id/delete', bearcat.getRoute("todoController", "delete"));
app.get('/todo/:id/finish', bearcat.getRoute("todoController", "finish"));
});
app.use(router);
// start app
app.listen(config.port);
console.log('Server start on ' + config.port);
});
node server.js
项目完整的代码在 todo