给初学者 - Nodejs实现数据库增删改查的路由方式,可应用于多模块的复杂应用系统
给初学者 - Nodejs实现数据库增删改查的路由方式,可应用于多模块的复杂应用系统
在弄清楚javascript和node.js原理前,一上来就用各种大型框架,初学者会走很多弯路。 比如session管理,写个session类,用内存来管理,一般就足够应用了 - 不过本贴不涉及这块。
//app.js --非常简单 var http=require(‘http’) ,path=require(‘path’) ,fs=require(‘fs’) ,route=require(’./route.js’) ;
var session=new (require(’./session’))();
http.createServer(function(request,response){ route(request,response,session);
}).listen(3000);
//session.js function session(){ var sessions=[]; this.signIn(…){…} this.signOut(…){…} this.isInSession(…){…} } 下面推荐的是一种路由方式,仅供参考。
//route.js module.exports=function(req,res,session){ switch(req.url){ case ‘/signin’: //主页 错误页面 登入登出等 … break; case ‘/signout’: … break; case /file#…: returnFile(req,res,session); … break;
default:
returnData(req,res,session);
break;
}
}
//用来处理文件请求
function returnFile(req,res){ … *html, images, css, *.js… }
function returnData(req,res){ if(session.isInSession(req){ //检查是否登录(或者检查用户是否在权限范围内的类) var sql_json=JSON.parse(querystring.parse(url.parse(req.url).query)[‘q’]); routes[sql_json.m][sql_json.a](sql_json.v,function(err,data){ …
});
}else{
…
}
} var routes={ “module1”:{ “action1”:function(v,cb){require(‘module1.js’).fn_a(v,cb);} “action2”:function(v,cb){require(‘module1.js’).fn_b(v,cb);} } ,“module2”:{ “action1”:function(v,cb){require(‘module2.js’).fn_a(v,cb);} “action2”:function(v,cb){require(‘module2.js’).fn_b(v,cb);} } … }
//module1.js 实现数据增删改查及业务逻辑的模块 var mysql=require(’…’); function fn_a(v,cb){…cb();} function fn_b(v,cb){…cb();} exports.fn_a=fn_a; exports.fn_b=fn_b;
为了帮助初学者理解如何使用Node.js实现数据库的增删改查,并且适用于多模块的复杂应用系统,我们可以通过一个简单的例子来展示。这个例子将包括基本的路由设计、数据库操作以及模块化的设计方法。
目标
- 创建一个简单的Node.js服务器。
- 使用Express框架简化路由处理。
- 实现对数据库的基本CRUD操作。
- 模块化代码以支持多模块应用。
示例代码
安装依赖
首先确保你已经安装了express
和mysql
库。你可以通过以下命令安装:
npm install express mysql
文件结构
/project-root
|-- app.js
|-- route.js
|-- db.js
|-- module1.js
app.js
这是项目的入口文件。
const express = require('express');
const app = express();
const port = 3000;
// 加载路由
const route = require('./route');
// 中间件:解析JSON请求体
app.use(express.json());
// 设置路由
app.use('/', route);
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
db.js
用于数据库连接和操作。
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
connection.connect((err) => {
if (err) throw err;
console.log("Connected to the MySQL server.");
});
module.exports = connection;
module1.js
这是一个示例模块,用于执行数据库的增删改查操作。
const db = require('./db');
function createRecord(data, callback) {
const query = "INSERT INTO users SET ?";
db.query(query, data, callback);
}
function readRecords(callback) {
const query = "SELECT * FROM users";
db.query(query, callback);
}
function updateRecord(id, data, callback) {
const query = "UPDATE users SET ? WHERE id = ?";
db.query(query, [data, id], callback);
}
function deleteRecord(id, callback) {
const query = "DELETE FROM users WHERE id = ?";
db.query(query, id, callback);
}
module.exports = { createRecord, readRecords, updateRecord, deleteRecord };
route.js
定义路由处理函数。
const express = require('express');
const router = express.Router();
const module1 = require('./module1');
router.get('/users', (req, res) => {
module1.readRecords((err, results) => {
if (err) return res.status(500).send(err);
res.json(results);
});
});
router.post('/users', (req, res) => {
module1.createRecord(req.body, (err, result) => {
if (err) return res.status(500).send(err);
res.status(201).json(result);
});
});
router.put('/users/:id', (req, res) => {
module1.updateRecord(req.params.id, req.body, (err, result) => {
if (err) return res.status(500).send(err);
res.json(result);
});
});
router.delete('/users/:id', (req, res) => {
module1.deleteRecord(req.params.id, (err, result) => {
if (err) return res.status(500).send(err);
res.json(result);
});
});
module.exports = router;
总结
通过上述步骤,我们可以构建一个简单的Node.js应用,它能够处理HTTP请求并执行基本的数据库操作。这种方式不仅易于理解和维护,而且可以很容易地扩展到更复杂的多模块系统中。
先不说内容怎么样。。难道就真的不会用Markdown?
#一个简单的路由
本方法通过简单的路由定义,实现复杂的业务逻辑。 路由定义如下:
var routes={
"module1":{ //模块
"action1":function(v,cb){require('module1.js').fn_a(v,cb);} //引用功能模块1的操作1
,"action2":function(v,cb){require('module1.js').fn_b(v,cb);} //引用功能模块1的操作2
}
,"module2":{ //模块
"action1":function(v,cb){require('module2.js').fn_a(v,cb);} //引用功能模块2的操作1
,"action2":function(v,cb){require('module2.js').fn_b(v,cb);} //引用功能模块2的操作2
}
};
客户端ajax发送请求的url定义如下:
var v={
"m":"module1"
,"a":"action1"
,"v":{...}//发往服务器端的复杂的数据结构,根据业务需求而定
};
var url='query?q='+JSON.strignify(v});
服务器端url解析如下:
var querystring=require('querystring')
,url=require('url');
var sql_json=JSON.parse(querystring.parse(url.parse(req.url).query)['q']);
调用路由:
routes[sql_json.m][sql_json.a](sql_json.v,function(err,data){
...
});
下面为稍详细的代码
#服务器端
###app.js
var http=require('http')
,path=require('path')
,fs=require('fs')
,route=require('./routes/route.js');
var session=new (require(’./session’))();
http.createServer(function(request,response){
route(request,response,session);
}).listen(3000);
###session.js --通过内存管理session的类
function session(){
var sessions=[];
this.isInSession=function(req){…}
this.signIn=function(req){}
this.signOut=function(req){}
//从header里提取cookie信息
function objectifyCookie(req){
…
return u_id;}
}
}
##route.js
var querystring=require(‘querystring’)
,url=require(‘url’);
module.exports=function(req,res,session){
switch(req.url){
case ‘/’:
returnFile(‘index’,res);
break;
case ‘/signin’:
session.signIn(req,res);
break;
case ‘/signout’:
session.signOut(req,res);
break;
default:
returnData(req,res,session);
break;
}
}
function returnData(req,res,session){
if(!session.isInSession(req)){return …;}
var sql_json=JSON.parse(querystring.parse(url.parse(req.url).query)[‘q’]);
routes[sql_json.m][sql_json.a](sql_json.v,function(err,data){
…
});
}
var routes={
“module1”:{
“action1”:function(v,cb){(require(‘./module1.js’).fn_a(v,cb);}
,“action2”:function(v,cb){(require(‘./module1.js’).fn_b(v,cb);}
}
,“module2”:{
“action3”:function(v,cb){(require(‘./module2.js’).fn_c(v,cb);}
,“action4”:function(v,cb){(require(‘./module2.js’).fn_d(v,cb);}
}
};
function returFile(…){…}
##module1.js --负责具体业务逻辑的模块
//具体业务功能模块//module1.js
//引用node-mysql及其设置
var mysql=require(…);
function fn_a(v,cb){...}
function fn_b(v,cb){...}
exports.fn_a=fn_a;
exports.fn_b=fn_b;
//module2.js
var mysql=require(...);
function fn_c(v,cb){...}
function fn_d(v,cb){...}
exports.fn_c=fn_c;
exports.fn_d=fn_d;
##客户端
ajax函数
function queryData(v,cb,isPost){
var url=’query?q=’+JSON.strignify(v);
var req=new XMLHttpRequest();
req.onreadystatechange=function(){
if(req.readyState==4 && req.status==200){
if(JSON.parse(req.responseText).msg=='not login'){
renderSignIn();
} else{
return cb(null,req.responseText);
}
}
} ;
if(isPost){req.open('post',url,false);}else{req.open('get',url,false);}
req.send(null);
}
###调用ajax var v={ “m”:”module1" //此处可使用简单的模块别称或者序号 ,”a”:”query”//此处可使用简单的操作别称或者序号 ,”v”:{…} // 此处可根据业务逻辑定义复杂的数据结构 }; queryData(v,function(err,data){ var _data=JSON.parse(data); //获得服务器传来对象 … });
感觉太复杂了,我只用了几行代码就自动路由了
这代码也太那个撒了吧哈哈
请分享,谢谢!
新手看不懂这代码是什么意思,还是喜欢一个一个写路由,扩展性好
针对给定的背景信息,我们可以扩展route.js
、module1.js
等文件来实现基本的CRUD操作,并使用Express框架简化路由处理。以下是简化版的示例代码:
app.js
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
// 加载路由
require('./route')(app);
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
route.js
const express = require('express');
const router = express.Router();
const { handleModuleActions } = require('./module1');
router.get('/api/module1', async (req, res) => {
try {
const data = await handleModuleActions(req.query.q, 'action1');
res.json(data);
} catch (error) {
res.status(500).send(error.message);
}
});
router.post('/api/module1', async (req, res) => {
try {
const data = await handleModuleActions(req.body, 'action2');
res.json(data);
} catch (error) {
res.status(500).send(error.message);
}
});
module.exports = app => {
app.use('/api', router);
};
module1.js
const mysql = require('mysql');
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'test'
});
db.connect((err) => {
if (err) throw err;
console.log('MySQL Connected...');
});
function handleAction(action, data, callback) {
switch (action) {
case 'get':
db.query('SELECT * FROM users WHERE id = ?', [data.id], (err, results) => {
if (err) return callback(err);
callback(null, results);
});
break;
case 'create':
db.query('INSERT INTO users SET ?', data, (err, results) => {
if (err) return callback(err);
callback(null, results.insertId);
});
break;
case 'update':
db.query('UPDATE users SET ? WHERE id = ?', [data, data.id], (err, results) => {
if (err) return callback(err);
callback(null, results.affectedRows);
});
break;
case 'delete':
db.query('DELETE FROM users WHERE id = ?', [data.id], (err, results) => {
if (err) return callback(err);
callback(null, results.affectedRows);
});
break;
}
}
module.exports.handleModuleActions = handleAction;
解释
- app.js: 初始化Express应用并设置路由。
- route.js: 定义了API端点,如GET和POST,用于处理不同的操作。
- module1.js: 使用MySQL进行数据库的CRUD操作。
通过这种方式,你可以轻松地扩展到更多模块和更多的功能,同时保持代码的组织性和可维护性。