I have already introduced how to build an express operating environment NodeJS: Build an express framework-based operating environment ; so this article only introduces how to use express+MySQL to build a complete background project to achieve dynamic routing.
- express build project
- Connect to the database
- Encapsulate dynamic routing
1. Express generation project
//通过生成器生成项目
express + 项目名称 //命令行自动创建项目
cd +项目名称
npm install
npm start //按照提示执行以上代码,启动express项目
Modify the template rendering engine
npm i ejs --save //安装ejs模板
//app.js
var ejs=require('ejs')
app.set('views', path.join(__dirname, 'views'));
app.engine('html', ejs.renderFile);
app.set('view engine', 'html');
Two, connect to the database
First, you need to start the MySQL database;
Secondly, configure the connection database in the project;
1. Create a config folder in the project, and then create two files, index.js and db_config.js;
the content of the config/db_config.js file is as follows:
//mysql配置文件
mysql = {
host: "127.0.0.1", //这是数据库的地址
user: "root", //需要用户的名字
password: "", //用户密码 ,如果你没有密码,直接双引号就是
database: "passdatabase" //数据库名字
} //好了,这样我们就能连接数据库了
module.exports = mysql; //用module.exports暴露出这个接口,
The content of the config/index.js file is as follows:
var mysql = require('mysql');
var dbConfig = require('./db_config.js');
const pool=mysql.createPool(dbConfig);
function responseDoReturn(err,ret) {
let result={};
if(err) {
result={
code:'100',
msg: 'err'+err
};
} else {
result={
code:'0',
msg: 'success',
data:ret
}
}
return result
};
/**
* 封装query之sql带不占位符func
*/
function query(sql, callback) {
pool.getConnection(function (err, connection) {
if(err){
callback(responseDoReturn(err,null));
}else{
connection.query(sql, function (err, rows) {
connection.release();
callback(responseDoReturn(err,rows));
});
}
});
}
/**
* 封装query之sql带占位符func
*/
function queryArgs(sql,args, callback) {
pool.getConnection(function (err, connection) {
if(err){
callback(responseDoReturn(err,null));
}else{
connection.query(sql, args,function (err, rows) {
connection.release();
callback(responseDoReturn(err,rows));
});
}
});
}
//exports
module.exports = {
query: query,
queryArgs: queryArgs,
}
2. Create a sql folder. Under the folder, modules are distinguished according to the tables of the database. I wrote a user.js;
the content of the sql/user.js file is as follows:
var user_sql={
insertOne:'insert into user (username,password,remark) values (?,?,?)',
deleteOne:'delete from user where id = ?',
updateOne:'update user set username = ?,password = ?,remark = ? where id = ?',
selectOne:'select * from user where id = ?',
selectAll:'select * from user',
selectOneByName:'select * from user where username = ?',
}
module.exports=user_sql
3. Create a model folder. Under the folder, modules are distinguished according to the tables of the database. I wrote a user.js;
the content of model/user.js is as follows:
var userSql = require('../sql/user.js');
var db = require('../config/index.js');
function getUser(req,res,callback){
db.queryArgs(userSql.selectOneByName, req.body.username,function (result) {
callback(result);
});
}
function addUser(req,res,callback){
db.queryArgs(userSql.insertOne, [req.body.username,req.body.password,req.body.remark],function (result) {
callback(result);
});
}
module.exports = {
getUser:getUser,
addUser:addUser
}
4. Create a controller folder. Under the folder, modules are distinguished according to the table of the database. I wrote a user.js;
the content of controller/user.js is as follows:
let model = require('../model/user.js');
let api = {
login(req, res, next) {
},
register(req, res, next) {
new Promise((resolve, reject) => {
model.getUser(req, res, (result) => {
if (result.code == "0") {
if (result.data.length) {
res.json({
code: '0',
msg: "用户已存在"
})
} else {
resolve(result)
}
} else {
res.json(result)
}
})
}).then((result) => {
if (!result.data.length) {
model.addUser(req, res, (result) => {
if (result.code == '1') {
res.cookie("userId", result.data.insertId, {
path: '/',
maxAge: 1000 * 60 * 60
});
}
res.json(result)
})
}
})
}
}
module.exports = api
4. I wrote a user.js under the routes folder;
the content of routes/user.js is as follows:
var express = require('express');
var router = express.Router();
var api=require('../controller/user.js');
/* GET users listing. */
router.post('/login', function(req, res, next) {
api.login(req, res, next)
});
router.post('/register', function(req, res, next) {
api.register(req, res, next)
});
module.exports = router;
3. Encapsulate dynamic routing
Create the untils folder and create the index.js file with the following contents;
/**
* 动态遍历目录加载路由工具
* author: bling兴哥
*/
var fs = require("fs");
var path=require('path');
// 动态路由
var loadRoute = {
path : path.join(__dirname,'../routes/'),
app : null,
// 遍历目录
listDir : function(dir){
var fileList = fs.readdirSync(dir,'utf-8');
for(var i=0;i<fileList.length;i++) {
var stat = fs.lstatSync(dir + fileList[i]);
// 是目录,需要继续
if (stat.isDirectory()) {
this.listDir(dir + fileList[i] + '/');
} else {
this.loadRoute(dir + fileList[i]);
}
}
},
// 加载路由
loadRoute : function(routeFile){
console.log(routeFile);
var pathArr=routeFile.split('\\');
var routeName=pathArr[pathArr.length-1].replace(/(.*)\.\w+$/,'$1');
var route = require(routeFile.substring(0,routeFile.lastIndexOf('.')));
this.app.use("/"+routeName,route);
},
// 初始化入口
init : function(app,path){
if(!app){
console.error("系统主参数App未设置");
return false;
}
this.app = app;
this.path = path?path:this.path;
this.listDir(this.path);
}
};
module.exports = loadRoute;
The modified content in the app.js file is as follows:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var loadRoute=require('./untils/index.js');
// var bodyParser=require('body-parser');
var ejs=require('ejs');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', ejs.renderFile);
app.set('view engine', 'html');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req,res,next){
if(req.cookies.userId){
next()
}else{
if(req.path=="/user/login"||req.path=="/user/register"){
next()
}else{
res.json({
code:'10001',
msg:"当前未登录",
result:""
})
}
}
})
loadRoute.init(app);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Note:
1. When the front-end uses the vue framework to send a request through axios, the parameter re.body={
{username:'222',password:'sss'}:''} obtained in the background can be modified on the front-end as follows:
修改:config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
为:config.headers['Content-Type'] ="application/json";