快速入门(nodejs)
海边的小溪鱼 2017-07-14 NodeJS
Node.js基础(Express + Mysql 实现 Api 接口的开发)
热启动:让我们在修改代码的情况下,不需要再重新启动项目
安装 nodemon:npm install -g nodemon(不是在项目下安装,而是桌面 cmd 全局安装)
运行 js 文件:node xxx.js 替换成 nodemon xxx.js(如果运行时权限报错可以这样:npx nodemon xxx.js)
# fs-文件系统模块
# 1-1. 读取文件内容(readFile)
fs.readFile() 方法:用来读取指定文件中的内容
// 导入 fs 模块
const fs = require("fs")
// 读取文件内容:fs.readFile("文件路径", "编码格式", 回调函数)
fs.readFile("./files/1.txt", "utf8", function(err, dataStr) {
console.log(err); // 读取成功时值为 null;读取失败时值为错误对象
console.log(dataStr); // 读取失败值为 undefined
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 1-2. 判断文件是否读取成功
// 导入 fs 模块
const fs = require("fs")
fs.readFile("./files/1.txt", "utf8", (err, dataStr) => {
if (err) {
return console.log("读取失败:" + err.message);
}
console.log("读取成功:" + dataStr);
})
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 2-1. 写入文件内容(writeFile)
fs.writeFile() 方法:用来读取指定文件中的内容
// 导入 fs 模块
const fs = require("fs")
// 读取文件内容:fs.writeFile("文件路径", "写入的内容", 回调函数)
fs.writeFile("./files/2.txt", "abcd", function (err) {
if (err) {
return console.log("写入失败:" + err.message);
}
console.log("写入成功");
})
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 3-1. 处理路径问题
const fs = require("fs")
// 导入 path 模块
const path = require("path")
// 1. path.join() 方法:路径拼接
const fullPath = path.join(__dirname, "./files/1.txt") // __dirname:表示当前所处路径
console.log("拼接后的路径为:" + fullPath);
fs.readFile(fullPath, "utf8", (err, dataStr) => {
if(err) {
return console.log("读取失败" + err.message);
}
console.log("读取成功:" + dataStr);
})
// 注意: ../ 会抵消前面的路径(相当于删除上一层路径)
// const pathStr = path.join("/a", "/b/c", "../../", "./d")
// console.log(pathStr); // /a/d
// 2. path.basename() 方法:可以从一个文件路径中,获取到文件名称部分
let fpath = path.basename("/a/b/c/index.html", ".html")
console.log("文件名称为:" + fpath); // index
// 3. path.extname() 方法:获取路径中的扩展名部分
let epath = path.extname("/a/b/c/index.html")
console.log(epath); // .html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# http 模块
# 1-1. 创建基本的 Web 服务器
// 1. 导入 http 模块
const http = require("http")
// 2. 创建 web 服务器实例
const server = http.createServer()
// 3. 绑定 request 事件,监听客户端的请求
server.on("request", (req, res) => {
// req 是请求对象,包含客户端相关的数据和属性
const str = `本次请求的地址为:${req.url}, 请求类型为:${req.method}`
// res.setHeader() 方法:设置 Content-Type 响应头(解决中文乱码的问题)
res.setHeader("Content-Type", "text/html; charset=utf-8")
// res.end() 方法:将内容响应给客户端(并结束请求)
res.end(str)
})
// 4. 启动服务器
server.listen(80, () => {
console.log("server running at http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1-2. 根据 url 响应不同的内容
// 1. 导入 http 模块
const http = require("http")
// 2. 创建 web 服务器实例
const server = http.createServer()
// 3. 服务器实例绑定 request 事件
server.on("request", (req, res) => {
// 请求的地址
const url = req.url
// 要响应的内容
let content = "<h1>404 Not found!</h1>"
// 设置 Content-Type 响应头(解决中文乱码的问题)
res.setHeader("Content-Type", "text/html; charset=utf-8")
// 根据请求地址响应不同内容
if(url === "/" || url === "/index.html") {
content = "<h2>首页</h2>"
} else if(url === "/about.html") {
content = "<h2>关于</h2>"
}
// 将内容响应给客户端
res.end(content)
})
// 4. 启动服务器
server.listen(80, () => {
console.log("server running at http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Express 框架
Express 是基于 Node.js 平台,快速、开放、极简的 Web 开发框架
安装:npm install express --save
注意:项目下执行安装命令后,会自动生成 node_modules 和 package-lock.json 文件
# 1-1. 基于 Express 创建 Web 服务器
// 1. 导入 express
const express = require("express")
// 2. 创建 web 服务器
const app = express()
// 3. 启动服务器
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 1-2. 监听 GET 和 POST 请求
const express = require("express")
const app = express()
/*
app.get("请求地址", "回调函数"):监听 get 请求
app.post("请求地址", "回调函数"):监听 post 请求
*/
// 4. 监听 get 请求
app.get("/video", (req, res) => {
// 向 客户端 响应一个 json 对象
res.send({ name: "张三", age: 18 })
})
app.post("/login", (req, res) => {
// 向 客户端 响应一个 文本内容
res.send("请求成功")
})
app.get("/", (req, res) => {
// req.query 默认是一个空对象(获取 客户端发起请求时 携带的参数)
console.log(req.query);
res.send(req.query)
})
app.get("/user/:id", (req, res) => {
// req.params 默认是一个空对象(获取 客户端发起请求时 携带的动态参数)
console.log(req.params);
res.send(req.params)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
// 注意:不推荐将路由挂载到 app 上,而是推荐将路由抽离为单独的模块(详见下一章"express路由")
// app.get() 就是路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 2-1. 托管静态资源
express.static() 方法:可以非常方便的创建一个静态资源服务器(将我们的静态网站对外开放)
const express = require("express")
const app = express()
// 对外提供静态资源(新建 public 文件夹,里面存放 css + js + html 的静态网站)
app.use(express.static("./public"))
// 对外开放多个静态资源可以这样写
app.use("/files", express.static("./public")) // http://127.0.0.1/files
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Express 路由
# 1-1. 模块化路由
// 这里是 api/router.js 文件(用于封装 api 接口)
// 1. 导入 express
const express = require("express")
// 2. 创建路由对象
const router = express.Router()
// 3. 挂载路由
router.get("/video/list", (req, res) => {
res.send("获取视频列表成功")
})
router.post("/video/add", (req, res) => {
res.send("添加视频成功")
})
// 4. 向外导出路由对象
module.exports = router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const express = require("express")
const app = express()
// 1. 导入我们自己封装好的路由模块
const router = require("./api/router")
// 2. 注册路由模块,并为路由模块添加统一的访问前缀
app.use("/api", router) // app.use() 函数的作用:用来注册全局中间件
// 3. 客户端发起请求时的地址为:http://127.0.0.1/api/video/list
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 2-1. 全局中间件
// express 的中间件:本质上就是一个函数(相当于请求拦截器)
const express = require("express")
const app = express()
/*
// 定义一个最简单的中间件函数(注意:中间件函数中,必须包含 next 参数)
const mw = function(req, res, next) {
console.log("这是最简单的中间件");
// next() 表示放行,中间件相当于 vue 中的导航守卫(如:判断用户登录,登录成功则放行,跳转页面,请求数据)
next()
}
// 将 mw 注册为 全局生效 的中间件
app.use(mw)
*/
// 简写
app.use((req, res, next) => {
console.log("这是最简单的中间件");
next()
})
// 发起请求后,会先执行中间件函数(会把这次请求先交给中间件处理,再响应数据给客户端)
app.get("/", (req, res) => {
console.log("调用了 / 这个路由");
res.send("首页")
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 2-2. 体验中间件的作用
const express = require("express")
const app = express()
/*
中间件函数中为 req/res 挂载自定义属性,
在 路由模块中 可以获取 中间件中挂载的自定义属性值
*/
// 定义中间件:中间件函数中的 req 和 res 是和路由模块中的 req/res 之间是共享的(共享同一个req/res)
app.use((req, res, next) => {
const time = Date.now()
req.startTime = time // 为 req 对象挂载自定义属性,并把时间共享给后面所有的路由(给所有的路由模块中的 req 对象都添加一个时间属性)
next()
})
// 路由模块1
app.get("/", (req, res) => {
res.send("首页" + req.startTime) // 获取中间件函数中,自定义属性值
})
// 路由模块2
app.get("/video", (req, res) => {
res.send("视频页" + req.startTime)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
/*
使用中间件的注意事项:
1. 一定要在 路由模块 之前定义中间件(除"错误级别中间件"以外的中间件)
2. 中间件函数必须有 next 参数,且一定要调用 next(), next() 之后不要写代码
3. 连续调用多个中间件时,多个中间件之间共享 req/res
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 2-3. 定义多个全局中间件
const express = require("express")
const app = express()
// 全局中间件1
app.use((req, res, next) => {
console.log("调用了全局中间件1");
next()
})
// 全局中间件2
app.use((req, res, next) => {
console.log("调用了全局中间件2");
next()
})
// 客户端请求到达服务器后,先调用中间件1,再调用中间件2(按照中间件定义的顺序一次调用),最后再执行路由模块中的代码
app.get("/", (req, res) => {
console.log("首页,我是最后执行的");
res.send(req.url)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 2-4. 局部中间件
const express = require("express")
const app = express()
// 定义中间件函数
const mw1 = function(req, res, next) {
console.log("这是中间件函数");
next()
}
// mw1 这个中间件只在"当前路由模块"中生效,这种用法属于"局部生效的中间件"
app.get("/", mw1, (req, res) => {
console.log("首页,我是最后执行的");
res.send(req.url)
})
// mw1 中间件不会影响到这个路由模块
app.get("/user", (req, res) => res.send("用户"))
// 定义多个局部中间件
// app.get("/", [mw1, mw2], (req, res) => res.send("首页"))
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3-1. 中间件的分类(错误级别中间件)
/**
* 中间件的分类:
* 1.应用级别的中间件:绑定到app.get()、app.post()、app.use() 实例上的中间件(如之前定义的全局中间件/局部中间件)
* 2.路由级别的中间件:绑定到 express.Router() 实例上的中间件
* 3.错误级别的中间件:用于捕获整个项目中发生的异常错误(防止程序异常崩溃),有4个形参分别是 err,req,res,next(注意:定义在路由之后)
* 4.内置的中间件:Express 内置了 3 个常用的中间件
* (1). express.static:托管静态资源(无兼容性)
* (2). express.json:解析 JSON 格式的请求体数据(4.16.0+ 版本)
* (3). express.urlencoded:解析 URL-encoded 格式的请求体数据(4.16.0+ 版本)
* 5. 第三方的中间件:由第三方开发出来的中间件(如:在 express@4.16.0 之前,使用 body-parser 中间件来解析请求体数据)
* 6. 自定义的中间件:自己手动模拟一个类似于 express.urlencoded 这样的中间件,来解析 POST 提交到服务器的表单数据
*/
const express = require("express")
const app = express()
// 路由模块:当路由模块发生错误时,会调用错误级别中间件()
app.get("/", (req, res) => {
throw new Error("服务器内部错误!") // 人为制造错误
res.send("首页")
})
// 错误级别中间件:定义在路由之后,捕捉路由模块中的错误(异常捕获),相当于 try catch
app.use((err, req, res, next) => {
res.send("发生了错误:" + err.message)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 3-2. 中间件的分类(内置中间件)
/**
* 内置的中间件:Express 内置了 3 个常用的中间件:
* (1). express.static:托管静态资源(无兼容性)
* (2). express.json:解析 JSON 格式的请求体数据(4.16.0+ 版本)
* (3). express.urlencoded:解析 URL-encoded 格式的请求体数据(4.16.0+ 版本)
* 第三方的中间件:由第三方开发出来的中间件(如:在 express@4.16.0 之前,使用 body-parser 中间件来解析请求体数据)
* (1). 安装:npm install body-parser
* (2). 导入第三方中间件:const parser = require("body-parser")
* (3). 注册并使用:app.use(parser.urlencoded({ extended: false }))
*/
const express = require("express")
const app = express()
// 使用 app.use() 注册中间件
// 1. express.json 中间件:解析表单中的 JSON 格式的数据
app.use(express.json())
// 2. express.urlencoded 中间件:解析表单中的 url-encoded 格式的数据
app.use(express.urlencoded({ extended: false }))
app.get("/user", (req, res) => {
// 默认情况下,如果没有注册解析表单数据的中间件,则 req.body 默认等于 undefined
console.log(req.body); // 接收客户端发送过来的请求体数据(包括 json 和 urlencoded 格式的数据)
})
app.listen(80, ()=> {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 3-3. 中间件的分类(自定义中间件)
// 自己手动模拟一个类似于 express.urlencoded 这样的中间件,来解析 POST 提交到服务器的表单数据
const express = require("express")
const app = express()
// 3-2. 导入 qs 模块
const qs = require("querystring")
// 1. 自定义的中间件:解析表单数据的中间件
app.use((req, res, next) => {
// 1. 定义一个变量,用于存储客户端发送到服务器的完整数据
let str = ""
// 2. 监听 req 的 data 事件:用于获取客户端发送到服务器的数据
req.on("data", (chunk) => {
str += chunk // str = str + chunk
})
// 3-1. 监听 req 的 end 事件:用于处理完整的请求体数据
req.on("end", () => {
// 3-3. 使用 qs.parse() 把字符串格式的请求数据,解析成对象格式
const body = qs.parse(str)
// console.log(body);
// 3-4. 将解析出来的数据,挂载为 req.body 属性
req.body = body
// 3-5
next()
})
})
// 客户端发起请求后,会先执行自定义中间件函数,再执行路由模块中的代码
app.post("/user", (req, res) => {
res.send(req.body)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 4-1. 中间件的封装
// 这里是 body-parse-08/body-parse.js 文件(用于封装中间件)
// 3-2. 导入 Node.js 内置的 querystring 模块
const qs = require("querystring")
const bodyPaeser = (req, res, next) => {
// 1. 定义一个变量,用于存储客户端发送到服务器的完整数据
let str = ""
// 2. 监听 req 的 data 事件:用于获取客户端发送到服务器的数据
req.on("data", (chunk) => {
str += chunk // str = str + chunk
})
// 3-1. 监听 req 的 end 事件:用于处理完整的请求体数据
req.on("end", () => {
// 3-3. 使用 qs.parse() 把字符串格式的请求数据,解析成对象格式
const body = qs.parse(str)
// console.log(body);
// 3-4. 将解析出来的数据,挂载为 req.body 属性
req.body = body
// 3-5
next()
})
}
module.exports = bodyPaeser
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const express = require("express")
const app = express()
// 导入自己封装的中间件模块
const bodyParser = require("./body-parse-08/body-parse.js")
// 将自定义的中间件函数,注册为全局可用的中间件
app.use(bodyParser)
app.post("/user", (req, res) => {
res.send(req.body)
})
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 5-1. 中间件注意事项
全局中间件:在 app.js 入口文件中,使用 app.use() 定义全局中间件
// 1. 中间件函数必须定义在路由之前,且有 3 个参数,依次是:req res next,next 是必须参数
app.use((req, res, next) => {
next() // 2. 必须调用 next(),表示:流转(交给下一个中间件或路由处理),且 next() 后面不要写代码
})
// 中间件2...
// 3. 当客户端发起请求时,会先执行中间件函数中的代码,再执行路由模块中的代码
app.get("/", (req, res) => {})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
// 中间件1
app.use((req, res, next) => {
req.uname = "张三" // 1. 可以为 req 和 res 挂载自定义属性或方法
next()
})
// 中间件2
app.use((req, res, next) => {
console.log(req.uname) // 2. 多个全局中间件之间的 req 和 res 是共享的
next()
})
// 注意:客户端发起请求时,会先执行中间件1,再执行中间件2,最后执行路由模块中的代码
// 路由模块
app.get("/", (req, res) => {
res.send(req.uname) // 3. 路由模块中可以获取到全局中间件中挂载的属性/方法
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
局部中间件:通过 app.get()、app.post()、等这种方式调用的中间件,属于"局部中间件"
// 中间件1
const mw1 = function(req, res, next) {
req.age = 18
next()
}
// 中间件2...
// 局部中间件:mw1 这个中间件,只在"当前路由模块"中生效
app.get("/", mw1, (req, res) => { // 可以连续调用多个中间件 [mw1, mw2]
res.send(req.age) // 使用了 mw1 这个中间件,就可以获取到该中间件身上挂载的自定义属性/方法
})
// 注意:连续调用多个中间件时,多个中间件之间共享 req 和 res
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
错误级别中间件:用于捕捉路由模块中的错误,必须定义在路由模块之后,且有 4 个参数依次为:
errreqresnext
app.get("/", (req, res) => {})
// 错误级别中间件:必须定义在路由模块之后,用于捕获路由模块中的错误,只有在路由发生错误时才会执行
app.use((err, req, res, next) => {
res.send("发生了错误:" + err.message)
next()
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 创建基本的服务器(解决跨域问题)
// 我是 api/video.js 文件:所有的 api 接口都封装在这里
// 1. 导入 express
const express = require("express")
// 2. 创建路由对象
const router = express.Router()
// 3. 挂载路由
router.get("/video/list", (req, res) => {
// req.query() 方法:获取客户端发送到服务器的数据
const query = req.query
// res.send() 方法:向客户端响应内容
res.send({
status: 0, // 0 表示处理成功,1 表示处理失败
msg: "GET 获取视频列表成功", // 状态描述
data: query // 响应给客户端的数据(将来是将 数据库 中的数据,转化为 json 数据相应给客户端的)
})
})
router.post("/video/add", (req, res) => {
// req.body() 方法:获取请求体中的数据(url-encoded 格式)
const body = req.body
res.send({
status: 0,
msg: "POST 添加视频成功",
data: body
})
})
/*
* req.query() 方法:用于获取客户端发起 GET 请求时,所携带的 query 参数
* req.body() 方法:用于获取客户端发起 POST 请求时,所携带的 body 参数(urlencoded格式)
* 注意:请求体(body)参数有多种数据格式,如:urlencoded、json等,需要注册中间件来解析不同格式的数据
*/
// 4. 向外导出路由对象
module.exports = router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
* 解决接口跨域问题的方案有两种:
* 1. CORS:是 Express 的一个第三方中间件,可以很方便的解决跨域问题(主流的解决方法,推荐使用)
* (1). 安装:npm install cors
* (2). 导入:const cors = require("cors")
* (3). 注册使用:app.use(cors())
* 2. JSONP:只支持 GET 请求,有缺陷的解决方案
*/
// 1. 导入 express
const express = require("express")
// 2. 创建服务器实例
const app = express()
// 5. 配置解析表单数据的中间件:用于解析 post 请求时的,请求体中的数据
app.use(express.urlencoded({ extended: false }))
// 6. 使用 cors 中间件,来解决跨域问题
const cors = require("cors")
app.use(cors())
// 4-1. 导入封装好的路由模块(api接口)
const router = require("./api/video")
// 4-2. 注册封装好的路由模块,并为路由模块添加统一的访问前缀
app.use("/api", router)
// 4-3. 客服端发起请求:http://127.0.0.1/api/video/list
// 3. 启动服务器
app.listen(80, () => {
console.log("http://127.0.0.1");
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Mysql 模块
- 初始化项目:npm init -y
- 项目中安装 mysql 模块:npm install mysql
# 1-1. 链接数据库
准备工作:从 phpStudy 中启动数据库,并创建一个名为 my_db_01 的数据库
// 1. 导入 mysql
const mysql = require("mysql")
// 2. 建立与 Mysql 数据库的链接关系
const db = mysql.createPool({
host: "127.0.0.1", // 数据库地址
user: "root", // 数据库用户名(登录数据库的账号)
password: "root", // 数据库密码(登录数据库的密码)
database: "my_db_01", // 数据库名
prot: 3306, // 数据库端口
})
// db.qurey() 方法:指定要执行的 sql 语句,通过回调函数拿到执行的结果
db.query("select * from users", (err, results) => {
if(err) return console.log(err.message)
console.log(results);
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2-1. 查询数据(select)
// 查询数据:查询 users 表中所有的数据
db.query("select * from users", (err, results) => {
if(err) return console.log(err.message)
// select 查询语句:返回的是一个数组,里面包含用户的对象信息
console.log(results);
})
1
2
3
4
5
6
2
3
4
5
6
# 2-2. 插入数据(insert into)
// 插入数据:向 users 表中,添加一条新的用户
const user = { username: "李四", password: "888888" }
const sqlStr = "insert into users (username, password) values (?, ?)" // ? 表示占位符
db.query(sqlStr, [user.username, user.password], (err, results) => { // 用 [] 数组,分别给 占位符 填充数据
if (err) return console.log(err.message);
// insert into 新增语句:返回的是一个对象,可以通过 affectedRows 属性,来判断是否新增数据成功
if (results.affectedRows === 1) {
console.log("数据添加成功");
}
})
// 便捷写法:数据对象的每个属性 和 数据表的字段 是一一对应的关系
const user = { username: "王五", password: "555555" }
const sqlStr = "insert into users set ?"
db.query(sqlStr, user, (err, results) => {
if(err) return console.log(err.message)
if (results.affectedRows === 1) {
console.log("数据添加成功");
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2-3. 更新数据(update)
// 更新数据:从 users 表中,修改一条用户数据
const user = { id: 3, username: "小五", password: "505050" }
const sqlStr = "update users set username=?, password=? where id=?" // ? 表示占位符
db.query(sqlStr, [user.username, user.password, user.id], (err, results) => { // 用 [] 数组,分别给 占位符 填充数据
if (err) return console.log(err.message);
// insert into 新增语句:返回的是一个对象,可以通过 affectedRows 属性,来判断是否新增数据成功
if (results.affectedRows === 1) {
console.log("更新数据成功");
}
})
// 便捷写法:数据对象的每个属性 和 数据表的字段 是一一对应的关系
const user = { id: 3, username: "王五", password: "555555" }
const sqlStr = "update users set ? where id=?"
db.query(sqlStr, [user, user.id], (err, results) => {
if (err) return console.log(err.message);
if (results.affectedRows === 1) {
console.log("更新数据成功");
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2-4. 删除数据(delete)
// 删除数据:从 users 表中,删除一条用户数据(建议根据 id 来删除数据)
const sqlStr = "delete from users where id=?"
db.query(sqlStr, 3, (err, results) => {
if (err) return console.log(err.message);
if (results.affectedRows === 1) {
console.log("删除数据成功");
}
})
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8