foreword
I shared an article about the interaction between Nodejs and MySQL database before . This article mainly talks about the usage of mysql module. Today I am going to share a Nodejs server-side MVC architecture, through the API provided by the server to complete the CRUD operation of the database.
Introduction to MVC
MVC is a project architecture idea, that is, the project is layered, and different layers are responsible for different responsibilities.
M layer: model model, business logic processing, more embodies database CRUD;
V layer: view view, responsible for data presentation;
C layer: controller controller, responsible for business processes (communication bridge between V and M)
The embodiment of MVC in express project:
database preparation
-- 创建数据库(不存在时才创建)
CREATE DATABASE IF NOT EXISTS nodejs_mysql_db DEFAULT CHARSET utf8;
-- 创建users表(不存在时才创建)
CREATE TABLE IF NOT EXISTS `users` (
`id` INT(8) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(10) NOT NULL,
`age` INT(11) DEFAULT NULL,
`sex` VARCHAR(10) DEFAULT NULL,
`status` INT(1) DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
project code
Since my project is mainly used on the server side and provides APIs for front-end use, I will omit the content of views next.
1. app.js
project initiation file
const express = require("express");
const app = express();
const {global} = require("./config/global");
const user = require("./routes/user");
app.use(user);
app.listen(global.port,global.hostname,function (){
console.log('Express server listening at http://%s:%d',global.host,global.port);
})
2. config/global.js
global configuration file
exports.global = {
"host":"localhost",
"port":8899
}
3. config/db.js
database configuration file
const mysql = require("mysql");
const pool = mysql.createPool({
host:"localhost",
port:3306,
user:"root",
password:"1234qwer"
})
exports.UserDB = ()=>{
pool.config.connectionConfig.database = "nodejs_mysql_db";
return pool;
}
/*
// 可以通过这种方式,切换不同的DB实例
exports.BookDB = ()=>{
pool.config.connectionConfig.database = "ex_test";
return pool;
}
*/
exports.mysql = mysql;
4. models/userDao.js
M layer, user business logic processing, mainly CRUD operations of the database
const DB = require("../config/db");
const UserDB = DB.UserDB();
let DBResult = {};
DBResult.getUserList = function (cb){
UserDB.getConnection(function (err,conn){
if(err){return console.log(err)}
conn.query("SELECT * FROM users",function (error,results){
if(error){return console.log(error)}
console.log(conn.threadId);
conn.release();
cb(results);
})
})
}
DBResult.addUser = function (args,cb){
UserDB.getConnection(function (err,conn){
if(err){return console.log(err)}
// console.log(DB.mysql.format("INSERT INTO users(name,age,sex) VALUES ?",args));
conn.query("INSERT INTO users(name,age,sex) VALUES ?",args,function (error,results){
if(error){return console.log(error)}
console.log(conn.threadId);
conn.release();
cb(results);
})
})
}
DBResult.updateUser = function (args,cb){
UserDB.getConnection(function (err,conn){
if(err){return console.log(err)}
// console.log(DB.mysql.format("UPDATE users SET ? WHERE id = ?",args));
conn.query("UPDATE users SET ? WHERE id = ?",args,function (error,results){
if(error){return console.log(error)}
console.log(conn.threadId);
conn.release();
cb(results);
})
})
}
DBResult.deleteUser = function (args,cb){
UserDB.getConnection(function (err,conn){
if(err){return console.log(err)}
conn.query("DELETE FROM users WHERE id = ?",args,function (error,results){
if(error){return console.log(error)}
console.log(conn.threadId);
conn.release();
cb(results);
})
})
}
module.exports = DBResult;
5. routes/user.js
The user routing file is responsible for forwarding the API request to model/userDao.js, completing the CRUD operation of the database, and then returning the queried database data to the interface
const express = require("express");
const user = express.Router();
const userDao = require("../models/userDao");
user.all("*",express.json());
user.get("/users",function (req,res){
userDao.getUserList(function (userList){
res.send(userList);
});
})
user.post("/users",function (req,res){
userDao.addUser([req.body],function (addRes){
res.send(addRes);
})
})
user.put("/users/:id",function (req,res){
userDao.updateUser([req.body,req.params.id],function (updateRes){
res.send(updateRes);
})
})
user.delete("/users/:id",function (req,res){
userDao.deleteUser(req.params.id,function (deleteRes){
res.send(deleteRes);
})
})
module.exports = user;
Demonstration effect
0. There is no data in the newly created users table
1. Add new data
POST http://localhost:8899/users
2. Query data
GET http://localhost:8899/users
3. Update data
PUT http://localhost:8899/users/1
Then call the query interface, the data with id=1 has been updated
4. Delete data
DELETE http://localhost:8899/users/2
删除id=2的数据后再查询,仅剩id=1的数据
关键代码分析
以 POST http://localhost:8899/users 为例
客户端在调用服务端接口后,请求进入app.js,app.use(user) 将请求转发到 routes/user.js 里user.post 方法;
在user.post方法里,调用model/userDao.js的addUser方法;
那么怎么将user.post路由参数传递给 addUser方法,又怎么将addUser方法从数据库拿到的数据返回给user.post呢?
(1)定义addUser方法接收两个参数,一个args参数,一个cb代表的回调函数,conn.query查询完数据库后,执行cb回调函数,将结果返回给调用者。
注意: args 可以是单个参数,也可以是数组,如果没有路由参数,args也可以省略,如
getUserList 方法就只有一个cb回调函数。
// models/userDao.js
DBResult.addUser = function (args,cb){
UserDB.getConnection(function (err,conn){
if(err){return console.log(err)}
conn.query("INSERT INTO users(name,age,sex) VALUES ?",args,function (error,results){
if(error){return console.log(error)}
conn.release();
cb(results);
})
})
}
(2)调用addUser方法时,传递req.body作为args参数,再传一个函数作为回调函数,这个函数也接收一个参数,此参数实际上就对应conn.query里返回的results,然后通过res.send返回给接口
// routes/user.js
user.post("/users",function (req,res){
userDao.addUser([req.body],function (addRes){
res.send(addRes);
})
})
参考资料: