Nodejs+express后端学习笔记(1)

2024-01-09 11:27:37

1 Node.js安装

1、下载安装包:进入官网(https://nodejs.org/en),下载左侧的稳定版。
在这里插入图片描述

2、选择安装位置,不用勾选自动安装必要工具。
其他都默认Next。
在这里插入图片描述
配置环境,具体参考本文章:

https://blog.csdn.net/WHF__/article/details/129362462

2 Node.js使用

nodejs用来开发Web服务器(后端)。本文使用Visual Studio Code进行编写和调试。

2.1 REPL环境使用

命令行状态下输入:node,就可以进入。
可以进行简单的函数编写和计算。
1、输入函数:

> function add(a,b){
	return a+b;
}
> add(1,2)

会输出3。
在这里插入图片描述

2、输入调试:

console.log("hello")

在这里插入图片描述

2.2 基本知识、程序运行方法

1、JS文件的执行方式:js单线程执行,有异步任务,同步任务。

2、模块、包与commonjs规范:

  • 内置(Nodejs自带)
  • 第三方模块(安装在node-modules文件夹中)
    • npm
    • npm install 模块名 --save
    • npm uninstall 模块名
  • 自定义(项目里独立的js文件,根据commonjs规范定义)

3、运行js代码:node ****.js

2.3 第一个js文件

1、console
新建一个文件夹,在文件夹内新建helloworld.js文件,文件内容如下:

//helloworld.js
console.log("hello, world!");

运行代码,在终端控制台输入:node helloworld.js,程序将会反馈出hello, world!

在这里插入图片描述

2、function函数定义和调用
代码如下:

console.log("hello, world!");

function add(a,b){
    return a+b;
}

console.log(add(1,2));

控制台输入输出:

PS G:\Visual Studio\Nodejs_Project\nodejs_test> node .\helloworld.js
hello, world!
3

2.4 外部js文件导入

如果要使helloworld.js文件能够引用其他js文件,需要使用require函数。
1、在同级文件夹下新建utils.js文件,文件内容如下:

function add(a,b){
    return a+b;
}
function about(){
    return "服务器";
}
const name = "utils"

module.exports = {
    add,
    about,
    msg:"你好",
    name,
}

文件内能够定义变量、函数,并通过module.exports引出,以便其他文件调用。

2、文件引入:
helloworld.js文件中,使用require函数引入utils.js文件,然后调用文件内的参数,具体代码如下:

const util = require('./utils.js');

console.log("hello, world!");

console.log(util);
console.log(util.add(1,2));
console.log(util.about());
console.log(util.msg);
console.log(util.name);

3、代码运行:

PS G:\Visual Studio\Nodejs_Project\nodejs_test> node .\helloworld.js
hello, world!
{
add: [Function: add],
about: [Function: about],
msg: ‘你好’,
name: ‘utils’
}
3
服务器
你好
utils

2.5 export导出方法

1、导出对象

module.exports = {
	add,
	about,
	msg,
	...
}

2、导出值/属性

module.exports.add = add;
module.exports.about = about;
module.exports.msg = msg;
...

3、导出

export.add = add;
export about = about;
...

2.6 fs库使用、同步异步

1、fs库使用:如果要使用fs,管理文件系统。
直接const fs = require('fs')
有同步和异步的读取方法,两者都会按照顺序执行程序,但同步方法必须阻塞程序,等到数据读取出来,再继续执行。而异步方法则不会阻塞住程序,而是另外开一个回调函数(类似于中断处理函数),先执行下方代码,等到数据读取出来,再调用回调函数。因此,同步和异步的数据的呈现顺序会出现差异。代码如下:

const fs = require('fs');       // 文件系统模块

console.log("-------------------------------")
// 异步读取,函数运行和读取到值的时间不同,读取到值之后,再调用function
console.log("a1");
fs.readFile("./text1.txt", "utf-8", function(error, res) {
    if(error){
        console.log(error);
        return;
    }
    console.log(res);
});
console.log("b1");
console.log("c1");

// 同步读取文件,读取到文件之间把值给data
console.log("-------------------------------")
console.log("a2");
const data = fs.readFileSync("./text2.txt", "utf-8");
console.log(data);
console.log("b2");
console.log("c2");

代码运行如下,可以发现异步读取的函数输出结果不是按照顺序来的,但这种方法对于网络请求来说非常重要,能够避免因为网络速度较慢造成程序长时间阻塞。

-------------------------------
a1
b1
c1
-------------------------------
a2
text2
b2
c2
text1

2、异步方法也可以使用这种方式:相当于设置一个回调函数,等文件读取完成后调用回调函数。

function readFileCompletedHandle(error, res) {
    if(error){
        console.log(error);
        return;
    }
    console.log(res);
}

fs.readFile("./text1.txt", "utf-8", readFileCompletedHandle);

2.7 更多官方库

链接:

https://nodejs.p2hp.com/api/v19/documentation/

3 express框架

3.1 初始化工程

使用命令npm init来创建新工程。里面的设置全部默认,设置完成后会出现一个package.json文件。

//package.json
{
  "name": "nodejs_test",
  "version": "1.0.0",
  "description": "",
  "main": "helloworld.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

3.2 npm

进入npm官网,查找需要的第三方函数库,比如gulp、express、mqtt等。
链接:

https://npm.p2hp.com/

3.3 引入express

在项目文件夹下,输入命令:

npm add express

然后项目中就会安装各种依赖包。
在这里插入图片描述

3.4 http构建服务器

新建http_demo.js文件,代码如下:

// http_demo.js
var http = require('http')

// 通过http模块,创建web应用
var app = http.createServer((req,res) => {
    res.writeHead(200,{"ContentType":"text/plain"});
    res.end("hello world");
});

// 通过监听端口启动
app.listen(3000,'localhost');
console.log("http://localhost:3000");

运行程序,启动服务器,终端输入:

node http_demo.js

可以看到程序输出:

http://localhost:3000

进入该网址,就可以看到:

在这里插入图片描述

如果想要停止服务器运行,使用Ctrl+C组合键关闭。

3.5 express构建服务器

express对http库进行了封装。
新建app.js文件,代码如下:

// 导入express
const express = require("express");

const app = express()

app.get('/',(req,res)=>{
    res.send('Hello World Express!');
})

app.listen(3000,()=>{
    console.log("Express app at: http://localhost:3000");
})

运行程序:

node app.js

得到输出:

Express app at: http://localhost:3000

进入网页:
在这里插入图片描述

4 express路由

4.1 get、post、put、delete四种请求

app.js代码如下:

// 导入express
const express = require("express");

const app = express()

// get请求
app.get('/',(req,res)=>{
    res.send('Get Express!');
})
// post请求
app.post('/',(req,res)=>{
    res.send('Post Express!');
})
// put请求
app.put('/',(req,res)=>{
    res.send('Put Express!');
})
// delete请求
app.delete('/',(req,res)=>{
    res.send('delete Express!');
})

app.listen(3000,()=>{
    console.log("Express app at: http://localhost:3000");
})

输入node app.js运行服务器。

浏览器能够看到Get Express!

在这里插入图片描述

4.2 下载Postman验证

参考链接: https://blog.csdn.net/qq_37591637/article/details/88655294

输入网址:http://localhost:3000,左侧选择get、post、put、delete请求。点击Send,在底部就可以查看服务器返回的数据。
在这里插入图片描述
2、发送JSON格式数据:

//app.js
// get请求
app.get('/',(req,res)=>{
    res.send({"name":"小美","age":"18","message":"刚满十八岁~"});    // json格式数据
})

保存后重启服务器,刷新网页,可以看到:

在这里插入图片描述
postman也可以获得数据:

在这里插入图片描述
重启服务器比较麻烦,因此以下可以采用热部署。

4.3 热部署 nodemon

1、安装nodemon:
命令行输入:

npm install nodemon -d -g

-d的意思是作为依赖,可以自动添加到package.json中。
-g的意思是全局安装。

2、在package.jsonscript中修改:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
	"start": "nodemon app.js"
  },

3、使用npm start命令来启动服务器。

在这里插入图片描述
修改并保存app.js内的数据:

// get请求
app.get('/',(req,res)=>{
    // res.send('Get Express!');
    res.send({"name":"小兰","age":"16","message":"刚满十六岁~"});    // json格式数据
})

刷新浏览器,不用重启服务器,就可以看到返回数据的变化。

在这里插入图片描述

注意:如果出现nodemon : 无法将“nodemon”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再 试一次。问题的另外一个解决方法:

https://blog.csdn.net/yan_danfeng/article/details/109306687

4.4 路由模块化

将多个请求放置到其他文件。
新建router-demo.js,将部分app.js的代码移植到文件内,需要创建router对象,并在最后使用module.exports导出。

var express = require("express");

// 创建router对象
var router = express.Router();

// get请求
router.get('/',(req,res)=>{
    res.send({"name":"小兰","age":"16","message":"刚满十六岁~"});    // json格式数据
})
// post请求
router.post('/',(req,res)=>{
    res.send('Post Express!');
})
// put请求
router.put('/',(req,res)=>{
    res.send('Put Express!');
})
// delete请求
router.delete('/',(req,res)=>{
    res.send('delete Express!');
})

module.exports = router;

app.js修改为:

// 导入 express
const express = require("express");
const router = require("./router-demo");
const app = express();
// 绑定路由
app.use(router);

app.listen(3000,()=>{
    console.log("Express app at: http://localhost:3000");
})

重启服务器,可以看到服务依旧可以使用。

5 express中间件

5.1 中间件的请求参数

1、 req.query:查询字符串传递参数。查询字符串时URL中?后面的参数。
2、 req.params:包含路由定义的动态路由参数。动态路由参数是通过在路由路径中使用冒号:定义的。
3、 req.body:包含通过请求主体传递的参数,通常用于POST、PUT和DELETE请求中发送数据。需要使用中间件(body-parser)来解析请求主体。
4、 req.headers:包含请求中的头部信息。

5.1.1 修改状态Status

如果要get先返回状态(201),可以使用:

router.get('/',(req,res)=>{
    res.stauts(201).send({"name":"小兰","age":"16","message":"刚满十六岁~"});    // json格式数据
})

postman再次send以下,可以发现状态变化,从200变成201。
在这里插入图片描述

5.1.2 修改头部Headers

.set()可以组装头部,.end()表示一次响应的结束。

// get请求
router.get('/',(req,res)=>{
    res.set({"aHeader":"bHeader"});
    res.status(201).send({"name":"小兰","age":"16","message":"刚满十六岁~"});    // json格式数据
    res.end();
})

可以发现Headers内数据变化。
在这里插入图片描述

5.1.3 修改路由路径

如果从http://localhost:3000/user发送Get请求。
则可以修改app.js中绑定路由的参数,前面加上路径。

app.use('/user',router);

postman结果如下:依旧可以正常工作。
在这里插入图片描述

5.1.4 服务器读取字符串传递参数 query方法

获取params内的键值对数据,也就是?后面的数据。
1、修改router-demo.js内get请求的函数:

var express = require("express");


// 创建router对象
var router = express.Router();

// get请求
router.get('/',(req,res)=>{
    // 请求对象
    console.log("req请求",req);

    // 响应对象
    res.set({"aHeader":"bHeader"});
    res.status(201).send({"name":"小红","age":"16","message":"刚满十六岁~"});    // json格式数据
    res.end();
})
// post请求
router.post('/',(req,res)=>{
    res.send('Post Express!');
})
// put请求
router.put('/',(req,res)=>{
    res.send('Put Express!');
})
// delete请求
router.delete('/',(req,res)=>{
    res.send('delete Express!');
})

module.exports = router;

使用浏览器/postman发送一次请求,在VS Code的终端能够看到服务器的console.log调试信息,可以发现非常的长。

req请求 <ref *2> IncomingMessage {
  _readableState: ReadableState {
    highWaterMark: 16384,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [],
    awaitDrainWriters: null,
    [Symbol(kState)]: 1185840
  },
  ...
  [Symbol(kHeadersCount)]: 28,
  [Symbol(kTrailers)]: null,
  [Symbol(kTrailersCount)]: 0
}

2、如果浏览器或postman发送了键值对:

gender: female

网址则变成:

http://localhost:3000/user?gender=female

在这里插入图片描述
服务器读取方法如下:req.query.*****,*****是params中的Key值,输出的是value。

// get请求
router.get('/',(req,res)=>{
    // 请求对象
    console.log("req请求: ",req.query.gender);

    // 响应对象
    res.set({"gender":req.query.gender});
    res.status(201).send({"name":"小红","age":"16","message":"刚满十六岁~"});    // json格式数据
    res.end();
})

服务器控制台可以看到:

在这里插入图片描述

postman可以看到服务器返回了键值对gender:female给自己。

在这里插入图片描述

5.1.5 服务器读取动态路由参数 params方法

对于路由路径/user/:id,当发送请求到/user/123时,req,params.id将返回“123”。也就是获取id

router-demo.js文件修改如下,修改router.get('/:id', ...),并添加读取req.params.id

// get请求
router.get('/:id',(req,res)=>{
    // 请求对象
    console.log("req请求: ",req.query.gender);
    console.log("id: " + req.params.id);

    // 响应对象
    res.set({"gender":req.query.gender});
    res.status(201).send({"name":"小红","age":"16","message":"刚满十六岁~"});    // json格式数据
    res.end();
})

因此在刚才的网址和字符串传递参数之间添加动态路由参数:

http://localhost:3000/user/123?gender=female

在这里插入图片描述

发送之后,服务器调试信息如下:

req请求: female
id: 123

5.1.6 服务器读取POST请求的body

注意与5.3.4.2、5.3.4.3区分。
1、安装body-parser,命令行输入:

npm install body-parser

2、引入包、添加中间件、使用req.body读取数据。

//router-demo.js
var express = require("express");
const bodyParser = require("body-parser");

// 创建router对象
var router = express.Router();
router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: false }));
// ...
// post请求
router.post('/', (req,res)=>{
    console.log("post");
    console.log(req.body);
    res.send(req.body);
})
// ...
module.exports = router;

3、postman发送数据:
选择body、选择x-www-form-urlencoded格式、添加键值对{“nation”:“china”},发送POST请求。
在这里插入图片描述

4、可以看到服务器调试端输出:

post
[Object: null prototype] { nation: ‘china’ }

postman接收到:

在这里插入图片描述

5.2 express中间件的调用流程

1、客户端发送请求给服务器。
2、express服务器中对数据经过多次处理。
3、express服务器响应客户端请求。

express中间件的本质是function处理函数:

app.get('/', function(req, res, next){
	// 处理请求对象 req
	// 处理响应对象 res
	// ...
	next();
})

注意:中间件函数的形参列表中,必须包含next参数。而路由处理函数中只包含req和res。

5.2.1 定义全局中间件函数

修改app.js,在绑定路由之前加入中间件:

// 路由方法:
// 导入 express服务器
const express = require("express");
const router = require("./router-demo");
const server = express();

// 定义中间件函数
const fw = function(req, res, next){
    console.log("执行所有请求的前置函数")
    next();
};
server.use(fw);// 实例化使用中间件函数,发出任何请求时执行

// 绑定路由
server.use('/user',router);

server.listen(3000,()=>{
    console.log("Express server at: http://localhost:3000");
})

浏览器刷新一下,就可以在服务器调试端口看见中间件反馈的信息。

Express server at: http://localhost:3000
执行所有请求的前置函数
req请求: female
id: 123

多个中间件之间,共享同一份req和res,因此可以在上游的中间件中,统一为req和res对象添加自定义的属性或方法,供下游的中间件使用。

如下定义的就是全局中间件:

// 定义中间件函数1
const fw1 = function(req, res, next){
    console.log("前置函数1")
    next();
};
server.use(fw1);         // 实例化使用中间件函数,发出任何请求时执行

// 定义中间件函数2
const fw2 = function(req, res, next){
    console.log("前置函数2")
    next();
};
server.use(fw2);         // 实例化使用中间件函数,发出任何请求时执行

5.2.2 定义局部中间件函数

编写中间件函数,然后将函数放在GET请求函数中间,可以放置多个。

router.get('/', [
	middleWareFunction1,
	middleWareFunction2,
	..., 
], (req, res)=>{
	res.send("express get");
})

5.2.1中app.js的代码不变,修改router-demo.js的代码:

// router-demo.js
var express = require("express");


// 创建router对象
var router = express.Router();

// 定义局部中间件函数
const mwf1 = function(req, res, next){
    console.log("中间件函数1");
    next();
};
const mwf2 = function(req, res, next){
    console.log("中间件函数2");
    next();
};

// get请求
router.get('/:id', [mwf1, mwf2], (req,res)=>{
    // 请求对象
    console.log("req请求: ",req.query.gender);
    console.log("id: " + req.params.id);

    // 响应对象
    res.set({"gender":req.query.gender});
    res.status(201).send({"name":"小红","age":"16","message":"刚满十六岁~"});    // json格式数据
    res.end();
})
// post请求
router.post('/',(req,res)=>{
    res.send('Post Express!');
})
// put请求
router.put('/',(req,res)=>{
    res.send('Put Express!');
})
// delete请求
router.delete('/',(req,res)=>{
    res.send('delete Express!');
})

module.exports = router;

postman发送GET请求后,服务器显示如下:

前置函数1
前置函数2
中间件函数1
中间件函数2
req请求: female
id: 123

postman发送POST请求后,服务器显示如下:

前置函数1
前置函数2

可以发现mwf作为局部中间件,在get请求中被调用,但在post请求中没有被调用。而在app.js文件中的两个全局中间件依然被调用。

注意:
1、在路由之前注册中间件。
2、客户端发送过来的请求,可以连续调用多个中间件进行处理。
3、执行完中间件的业务代码之后,一定要调用next()函数。
4、中间件调用next()之后,一定不要再写额外的代码。
5、连续调用多个中间件时,多个中间件之间,共享req和res对象。

5.3 中间件级别

5.3.1 应用级别的中间件

通过app.use()或app.get()或app.post(),绑定到app实例上的中间件

5.3.2 路由级别的中间件

绑定到express.Router()实例上的中间件。和应用级别的中间件没有区别,只不过一个是绑定到app实例上,一个是绑定到router实例上。

5.3.3 错误级别的中间件

当项目发生异常,从而防止项目异常崩溃。错误级别的中间件函数有四个形参,分别为(err, req, res, next)。

1、修改router-demo.js的delete请求:

// router-demo.js
router.delete('/',(req,res)=>{
    res.status(5000);
    throw new Error("服务器发送错误");
})

throw new Error()为手动抛出一个错误信息。

2、添加错误中间件,由于要全局有效,因此放在app.js内,还要放在绑定路由的后面。

// app.js

// 导入 express服务器
const express = require("express");
const router = require("./router-demo");
const server = express();

// 定义中间件函数1
const fw1 = function(req, res, next){
    console.log("前置函数1")
    next();
};
server.use(fw1);         // 实例化使用中间件函数,发出任何请求时执行

// 定义中间件函数2
const fw2 = function(req, res, next){
    console.log("前置函数2")
    next();
};
server.use(fw2);         // 实例化使用中间件函数,发出任何请求时执行
// 绑定路由
server.use('/user',router);

// 错误中间件
const errorfw = (error, req, res, next) => {
    if(error){
        console.log('异常:',error.message);
        res.status(500).send('服务器发生错误:' + error.message);
    }else{
        next();
    }
}
server.use(errorfw);

server.listen(3000,()=>{
    console.log("Express server at: http://localhost:3000");
})

运行顺序是:中间件请求函数1、中间件请求函数2、router内的请求函数、错误中间件请求函数。

3、Postman发送DELETE请求。
服务器后台显示如下:

前置函数1
前置函数2
异常: 服务器发送错误

postman显示如下:
在这里插入图片描述

5.3.4 express内置的中间件

5.3.4.1 express.static()

express.static 快速托管静态资源,比如html文件、图片、css样式。
新建resource文件夹,在app.js文件中添加server.use(express.static('resource'));
代码如下:

// ...
// 绑定路由
server.use('/user',router);

// 错误中间件
const  errorfw = function(error, req, res, next){
    if(error){
        console.log('异常:',error.message);
        res.status(500).send('服务器发生错误:' + error.message);
    }else{
        next();
    }
}
server.use(errorfw);

server.use(express.static('resource'));

server.listen(3000,()=>{
    console.log("Express server at: http://localhost:3000/1.jpg");
})

resource文件夹下资源如下:
在这里插入图片描述

使用该中间件以管理文件夹内的图片、html、css,资源可通过浏览器访问,地址为:

http://localhost:3000/1.jpg
http://localhost:3000/1.html
http://localhost:3000/1.css

5.3.4.2 express.json()

注意与5.1.6、5.3.4.3区分。
express.json 解析JSON格式的body请求体数据。

1、修改app.js文件,在路由之前添加express.json(),代码如下:

// app.js
// ...
server.use(express.json());
server.use('/user',router);	// 绑定路由
// ...

2、在router-demo.js文件内,修改post请求,代码如下:

//router-demo.js
var express = require("express");

// 创建router对象
var router = express.Router();
// ...
// post请求
router.post('/', (req,res)=>{
    console.log("post");
    console.log(req.body);
    //res.send('Post Express!');
    res.send(req.body);
})
// ...
module.exports = router;

3、postman发送数据:选择POST、Body、raw、JSON,文本输入:

{
	"name":"小明"
}

点击Send发送请求。
在这里插入图片描述
4、postman接收到的信息如上图下侧,服务器调试端口如下:

post
{ name: ‘小明’ }

5.3.4.3 express.urlencoded()

注意与5.1.6、5.3.4.3对比。
express.urlencoded 解析URL-encoded格式的params请求体数据,也就是网址?后面的数据。

1、修改app.js文件,在路由之前添加express.urlencoded({extended:false}),代码如下:

// app.js
server.use(express.json());
server.use(express.urlencoded({extended:false}));
// 绑定路由
server.use('/user',router);

2、在router-demo.js文件内,修改post请求,代码如下:

//router-demo.js
var express = require("express");

// 创建router对象
var router = express.Router();
// ...
// post请求
router.post('/', (req,res)=>{
    console.log("post");
    console.log(req.body);
    const {username, password} = req.body;
    console.log("username: " + username);
    console.log("password: " + password);
    res.send(req.body);
})
// ...
module.exports = router;

3、postman选择POST请求、Body、x-www-form-urlencoded,添加键值对{“username”:“john”,“password”:“123456789”},发送请求。

在这里插入图片描述
4、服务器调试端口:

post
[Object: null prototype] { username: ‘john’, password: ‘1234568789’ }
username: john
password: 1234568789

postman显示:
在这里插入图片描述

5.3.5 第三方的中间件

6 express连接Mysql数据库

6.1 Mysql数据库配置

1、安装Mysql和Mysql Workbench,其他管理工具也可以,当然只用命令行也行。
2、新建连接:
主界面点击加号添加新的连接。这里可以创建默认Schema。输入密码,测试连接。

在这里插入图片描述

3、新建表 Table,添加元素与其对应的数据类型。

在这里插入图片描述
4、插入数据:
insert into gps_fence.user_login values(2,"root","woshiroot","123456789@qq.com","18200000000","0123456789",true);
然后点击闪电执行代码,下方显示出具体数据。

在这里插入图片描述

6.2 后端js连接测试

6.2.1 引入mysql库

终端输入:

npm install -s mysql

6.2.2 连接数据库

新建文件mysql-demo.js,测试数据库连接。
代码如下:

const mysql = require("mysql");

const connection = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'woshiroot',
    database:'gps_fence'
});
const table = 'user_login';

// 连接数据库
connection.connect((err) =>{
    if(err){
        console.log('Error connecting to MYSQL database: ' + err.stack);
        return;
    }else{
        console.log('Connect to MYSQL database as id' + connection.threadId);
    }
})

6.2.3 查询数据

js代码如下:

// 发送查询请求
const sqlStr = `select * from ${table}`;
connection.query(sqlStr, (err, results)=>{
    if(err){
        return console.log(err.message);
    }else{
        console.log(results);
    }
})

调试输出:

[
  RowDataPacket {
    user_id: 1,
    username: 'root',
    password: 'woshiroot',
    email: '14*********5@qq.com',
    phonenumber: '18206170000',
    worknumber: '0123456789',
    valid: 1
  },
  RowDataPacket {
    user_id: 2,
    username: 'root',
    password: 'woshiroot',
    email: '123456789@qq.com',
    phonenumber: '18200000000',
    worknumber: '0123456789',
    valid: 1
  }
]

6.2.4 插入数据

js代码如下:

//插入数据请求
const user_data = {
    username:'joe',
    password:'iamjoe20240107',
    email:'20240107@gmail.com',
    phonenumber:'1119491001',
    worknumber:'007',
};
const sqlStr1 = `insert into ${table} (username,password,email,phonenumber,worknumber) values (?,?,?,?,?)`;
// console.log(sqlStr1);
connection.query(sqlStr1, [
    user_data.username,
    user_data.password,
    user_data.email,
    user_data.phonenumber,
    user_data.worknumber
], (err, results)=>{
    if(err){
        return console.log(err.message);
    }else{
        console.log(results);
    }
})

查看Mysql Workbench,发现数据已经添加到数据库。
在这里插入图片描述

插入方法2:

//插入数据请求
const user_data = {
    username:'tom',
    password:'tomcat19990101',
    email:'19990101@gmail.com',
    phonenumber:'1119491011',
    worknumber:'008',
};
const sqlStr1 = `insert into ${table} (username,password,email,phonenumber,worknumber) values `;
// console.log(sqlStr1);
const user_data_amended = `(${Object.values(user_data).map(value => `"${value}"`).join(',')})`;
console.log(user_data_amended);
connection.query(sqlStr1 + user_data_amended, (err, results)=>{
    if(err){
        return console.log(err.message);
    }else{
        console.log(results);
    }
})

mysql数据库显示如下:

在这里插入图片描述

6.2.5 修改数据

6.2.6 删除数据

6.3 前端后端连接

前端发送GET请求,后端访问数据库,查询数据并发送给前端。

1、安装库:express、body-parser、cors、mysql

npm install -s express body-parser cors mysql

2、新建文件db.js,代码如下:

// db.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const mysql = require('mysql');

const app = express();
app.use(bodyParser.json());
app.use(cors());

// 结合Mysql数据库
const connection = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'root',
    database:'test'
})
const table = 'user_login';

// 连接数据库
connection.connect((err) =>{
    if(err){
        console.log('Error connecting to MYSQL database: ' + err.stack);
        return;
    }else{
        console.log('Connect to MYSQL database as id' + connection.threadId);
    }
})

// 查询数据请求
const sqlStr = `select * from ${table}`;
connection.query(sqlStr,(err, results, fields)=>{
    if(err){
        return console.log(err.message);
    }else{
        console.log(results);
        app.post('/api',(req, res)=> {
            res.send("none");
        })

        app.get('/api',(req, res)=> {
            if(req.query.key === "1234"){
                res.send(results);
            }else{
                res.send("wrong key");
            }
        })

        app.listen(3000,()=>{
            console.log("Express server at: http://localhost:3000");
        })
    }
})

3、Postman相当于前端,给服务器发送Get请求:

在这里插入图片描述

4、服务器给Postman返回的信息如下,正是Mysql内的数据。

[
    {
        "user_id": 1,
        "username": "root",
        "password": "woshiroot",
        "email": "123456789@qq.com",
        "phonenumber": "18200000000",
        "worknumber": "0123456789",
        "valid": 1
    },
    ...
]

6.4 工程接口API

工程中最好使用sequelize进行数据库池的管理。

6.4.1 安装 sequelize

npm install sequelize

Sequelize常用基本方法,方便对数据库进行增删改查的操作:

  • create(values, options):创建一个新的数据实例。
  • bulkCreate(records, options):批量创建多个数据实例。
  • findAll(options):查询满足条件的所有数据实例。
  • findOne(options):查询满足条件的第一个数据实例。
  • findByld(identifier, options):根据逐渐或者ID查询数据实例。
  • update(values, options):更新满足条件的数据实例的值。
  • destroy(options):删除满足条件的数据实例。
  • count(options):统计满足条件的数据实例的数量。
  • increment(fields, options):自增满足条件的数据实例的指定字段值。
  • decrement(fields, options):自减满足条件的数据实例的指定字段值。

6.4.2 创建数据库配置文件

新建config文件夹,新建dbconfig.js,代码如下:

//dbconfig.js
const Sequelize = require('sequelize');

// 创建一个新的Sequelize实例
const DB = new Sequelize("test","root","root",{ //分别为数据库名、用户名、密码
    host:'localhost',
    port: 3306,
    dialect:'mysql',
    pool:{
        max:100,
        min:0,
        idle:10000, // 10秒没有使用,释放该连接
    },
    logging:console.log,   //Sequelize日志输出方法
})

// 测试数据库连接
DB.authenticate().then(()=>{
    console.log("数据库连接成功");
}).catch((err)=>{
    console.log("数据库连接失败: ",err)
});

module.exports = DB;

6.4.3 创建模型

由于数据库的表内不同的字段有不同的数据类型,比如INTEGER、VARCHAR、TINYINT等等,需要nodejs对相应的数据进行类型匹配。field内字符串需要与mysql内完全相同。
可以新建多个模型文件,管理数据库内不同的表(Table)。
创建Models文件夹,创建user-login_model.js,代码如下:

// user-login_model.js
const DB = require("../config/dbconfig.js");
const Sequelize = require('sequelize');

// user_login是数据库的表名 define('表名',{字段})
// 模型与数据库表名的映射
const user_login_model = DB.define("user_login",{
    id:{
        primaryKey: true,
        type: Sequelize.INTEGER,
        field:"user_id",
        autoIncrement:true
    },
    username:{
        type:Sequelize.STRING(45),
        allowNull:true,
        field:"username"
    },
    password:{
        type:Sequelize.STRING(45),
        allowNull:true,
        field:"password"
    },
    email:{
        type:Sequelize.STRING(45),
        allowNull:true,
        field:"email"
    },
    phonenumber:{
        type:Sequelize.STRING(45),
        allowNull:true,
        field:"phonenumber"
    },
    worknumber:{
        type:Sequelize.STRING(45),
        allowNull:true,
        field:"worknumber"
    },
    valid:{
        type:Sequelize.BOOLEAN,
        allowNull:false,
        defaultValue:false,
        field:"valid"
    }
},{
    freezeTableName: true,      // 防止sequelize自动在表名后加s
    timestamps: false           // 禁用createAt和updateAt
});

module.exports = user_login_model;

6.4.4 添加路由

可以新建多个路由文件,每个路由文件内对相同表单进行不同路由的数据处理。
新建routes文件夹,新建user_login.js文件,代码如下:

// user_login.js
// 导入express
const express = require('express');

const router = express.Router();
const user_login_model = require("../Models/user_login_model.js");

// 获取所有学生信息:http://localhost:3000/user_login/search
router.get('/search', async (req, res, next) => {
    try {
      const result = await user_login_model.findAll({ raw: true });
      res.json({
        code: 1001,
        msg: result,
      });
    } catch (err) {
        next(err);
    }
});

// 添加user信息:http://localhost:3000/user_login/add
router.post('/add', async (req, res, next) => {
    try {
        const { username, password, email, phonenumber, worknumber, vaild } = req.body;
        await user_login_model.create({ username, password, email, phonenumber, worknumber, vaild });
        await res.json({
            code: 1001,
            msg: '数据插入成功',
        });
    } catch (err) {
        next(err);
    }
});

// 删除学生信息:http://localhost:3000/user_login/delete
router.post('/delete', async (req, res, next) => {
    try {
        const { id } = req.body;
        await user_login_model.destroy({ where: { id } });
        await res.json({
            code: 1001,
            msg: '删除成功',
        });
    } catch (err) {
      next(err);
    }
});

// 更新某条信息:http://localhost:3000/user_login/update
router.put('/update', async (req, res, next) => {
    try {
        const { id, valid } = req.body;
        const user = await user_login_model.findOne({ where: { id } });
        if (!user) {
            return res.json({
                code: 1002,
                msg: '查询失败',
            });
        }
        await user.update({ valid });
        await res.json({
            code: 1001,
            msg: 'valid更新成功',
        });
    } catch (err) {
      next(err);
    }
  });

// 错误处理中间件
router.use((err, req, res, next) => {
    console.error(err);
    res.status(500).json({
        code: 1002,
        msg: '服务器发生错误',
    });
});

module.exports = router;

6.4.5 添加引用

app.js文件内,导入路由文件,如果有多个路由,需要可以使用path方法进行添加。

// app.js
// 导入 express服务器
const express = require("express");
// 导入router
const path = require('path');
const app = express();
const cors = require('cors');

//路由加载之前使用内置中间件
app.use(express.json());
app.use(express.urlencoded({extended:false}));
app.use(cors());
app.use(express.static('resource'));

// 导入路由
const user_loginRouter = require(path.join(__dirname, 'routes', 'user_login.js'));
app.use('/user_login',user_loginRouter);

const device_infoRouter = require(path.join(__dirname, 'routes', 'device_info.js'));
app.use('/device_info',device_infoRouter);

app.listen(3000,()=>{
    console.log("Express server at: http://localhost:3000");
})

6.4.6 代码测试

1、运行程序,命令行输入:

npm start

2、Postman发送请求:

6.4.6.1 Get请求,查询数据:

请求地址:localhost:3000/user_login/search
返回数据如下:
在这里插入图片描述

6.4.6.2 Post请求,添加信息:

请求地址:http://localhost:3000/user_login/add
选择body,选择x-www-form-urlencoded,在下方添加需要输入数据表的键值对。

在这里插入图片描述
点击发送,Postman收到回复:

{
“code”: 1001,
“msg”: “数据插入成功”
}

查看数据表user_login:
在这里插入图片描述

6.4.6.3 Post请求,删除信息:

请求地址:http://localhost:3000/user_login/delete
选择body,选择x-www-form-urlencoded,只要输入id。

在这里插入图片描述

返回数据:

{
“code”: 1001,
“msg”: “删除成功”
}

数据表情况:可以看到user_id为5的数据已经被删除。

在这里插入图片描述

6.4.6.4 Put请求,修改数据:

请求地址:http://localhost:3000/user_login/update
请求数据:这里使用原始数据JSON格式发送(用法都一样的)。

在这里插入图片描述
返回数据:

{
“code”: 1001,
“msg”: “valid更新成功”
}

数据表情况:
在这里插入图片描述

文章来源:https://blog.csdn.net/qq_45362336/article/details/135266412
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。