如果文章有误还请指教!!!
1 后端
1) 项目搭建
安装express脚手架
执行命令, 全局安装脚本架(也称为项目生成器)
安装完成后, 在全局会多一个express命令
npm i express-generator -g
通过脚手加搭建项目
在根目录下, 执行命令
express --no-view backEnd
![后端express集成nodemon项目搭建环境_sql](//dev-img.mos.moduyun.com/20231020/74690c76-a1bb-43da-82a4-762ae0309f61.png)
- 在目录下创建一个backEnd(项目名字可自定义)的目录, 作为后端项目的目录
- --no-view: 创建一个数据服务, 不提供页面服务
安装相关依赖
进入`backEnd`目录, 执行命令, 根据`package.jsoon`中的依赖项, 安装项目所有的依赖
- cookie-parser: 解析cookie的中间件
- debug: 调试代码的中间件
- express: express框架包
- morgan: 记录日志的中间件
npm install安装package,json下配置的包
![后端express集成nodemon项目搭建环境_express_02](//dev-img.mos.moduyun.com/20231020/0a6f3d34-c0fa-4f87-9894-322b6d71d8de.png)
会在文件根目录下创建node_modules存放依赖相关的包
启动项目
将nodemon作为开发时依赖安装
使用nodemon启动项目,
包管理目录下就会有我们安装的nodemon的包
![后端express集成nodemon项目搭建环境_sql_03](//dev-img.mos.moduyun.com/20231020/7b3acdba-ee93-41c0-9ecd-6dc2b757e749.png)
会在package.json中, 生成devDependencies
"devDependencies": {
"nodemon": "^2.0.15"
}
修改pagckage.json中的脚本
![后端express集成nodemon项目搭建环境_sql_04](//dev-img.mos.moduyun.com/20231020/3531941b-10f1-438b-bd9c-9e43f04f6039.png)
![后端express集成nodemon项目搭建环境_express_05](//dev-img.mos.moduyun.com/20231020/d4f5d8b7-ac3a-4828-bd92-7b99fca3c64d.png)
修改启动脚本为nodemon启动。
执行
使用浏览器测试
访问本地3000端口
![后端express集成nodemon项目搭建环境_sql_06](//dev-img.mos.moduyun.com/20231020/e9e3acda-a3c8-4cdf-acf8-ce45946b0227.png)
安装mysql包
来访问数据库数据
![后端express集成nodemon项目搭建环境_mysql_07](//dev-img.mos.moduyun.com/20231020/118d9869-06f3-49e5-98df-5339ba4db471.png)
调用MySQL
方式一:
在根目录下创建db/index.js文件
// 1. 导入mysql包
const mysql = require("mysql")
// 2. 创建连接
const con = mysql.createConnection({
host: "localhost",
port: "3306",
user: "root",
password: "145869",
database: "db13",
// dateStrings: true,
timezone: "SYSTEM", //时间格式
})
//3.连接数据库
con.connect()
方式二:
在根目录下创建config/config.default.js (默认配置文件)文件,将mysql数据库相关配置封装,方便以后修改调用
module.exports = {
debug: true,
// 根mysql数据库相关的配置
mysql: {
host: "127.0.0.1",
port: 3306,
user: "root",
password: "145869",
database: "db13",
},
}
再在db/index.js里导入、调用
// 封装数据库的操作
// 1. 导入mysql包
const mysql = require("mysql")
// 导入配置文件
const { mysql: MySQLCon } = require("../config/config.default.js")
// 2. 创建连接
const con = mysql.createConnection({
host: MySQLCon.host,
port: MySQLCon.port,
user: MySQLCon.user,
password: MySQLCon.password,
database: MySQLCon.database,
// dateStrings: true,
timezone: "SYSTEM", //时间格式
})
//3.连接数据库
con.connect()
安装cors
cors这个包时解决跨域请问的
安装http-errors
HTTP异常的通用软件包
导入和注册我们安装的包(要使用必须进行导入注册)
在根目录下的app.js下注册使用
//导入express包
var express = require("express")
//导入内置模块path
var path = require("path")
//导入第三方模块(解析cookie)
var cookieParser = require("cookie-parser")
//导入第三方模块(记录日志)
var logger = require("morgan")
//导入跨域请求的模块
const cors = require("cors")
//导入创建 Express,Koa,Connect 等的 HTTP 错误。
var createError = require("http-errors")
//导入路由对象(模块化路由)
var indexRouter = require("./routes/index")
var usersRouter = require("./routes/users")
//实例化express对象
var app = express()
//注册记录日志中间件morgan
app.use(logger("dev"))
//注册解析请求体中间件(处理json格式的请求体)
app.use(express.json())
//注册解析请求体中间件(处理url格式的请求体)
//extended: false表示使用系统模块queryString来处理,true表示使用第三方模块qs来处理
app.use(express.urlencoded({ extended: false }))
//注册解析cookie数据的中间件
app.use(cookieParser())
//注册解析静态资源的中间件
app.use(express.static(path.join(__dirname, "public")))
/* 注册跨域请求的中间件 */
app.use(cors())
//注册路由对象(根据不同的访问路径,调用不同的路由对象进行处理)
app.use("/", indexRouter) //都有统一前缀
app.use("/users", usersRouter)
// 捕获404并转发到错误处理程序
app.use(function (req, res, next) {
next(createError(404))
})
// 错误处理程序
app.use(function (err, req, res, next) {
// 设置局部变量,仅在开发中提供错误
res.locals.message = err.message
res.locals.error = req.app.get("env") === "development" ? err : {}
// 呈现错误页
res.status(err.status || 500)
res.render("error")
})
//导出app实例对象
module.exports = app
流程图:
![后端express集成nodemon项目搭建环境_express_08](//dev-img.mos.moduyun.com/20231020/91c4a156-ae2b-4f40-9889-1207d783a925.png)
2) 实现获取所有用户
补充知识点.params、.query、.body
res.params
用于get请求
url路径为:http://localhost:3000/list/001/21
路由代码:
app.get('/list/:id/:age',(req,res)=>{
res.send(req.params)
//浏览器页面结果: {"id":"001","age":"21"}
})
res.query
用于get请求
url路径为:http://localhost:3000/form?username=1&pwd=1
路由代码:
app.get('/form',(req,res)=>{
console.log(req.query)
res.send(req.query)
// {"username":"1","pwd":"1"}
})
form表单:
<form action="http://localhost:3000/form" method="get">
用户名:<input type="text" name="username">
密码:<input type="text" name="pwd" id="">
<input type="submit">
</form>
res.body
用于post请求
url路径为:http://localhost:3000/form
路由代码:
app.post('/form',(req,res)=>{
console.log(req.body)
res.send(req.body)
// {"username":"1","pwd":"1"}
})
form表单:
<form action="http://localhost:3000/form" method="post">
用户名:<input type="text" name="username">
密码:<input type="text" name="pwd" id="">
<input type="submit">
</form>
配置db的方法模块
查询所有
/**
* 获取所有数据
* @param {string} sql : 执行的sql语句
* @return {promise}
*/
function getAll(sql) {
return new Promise((resolve, reject) => {
con.query(sql, (err, data) => {
if (err) {
reject(err.message)
}
resolve(data)
})
})
}
查询一个
/**
* 获取一个数据
* @param {string} sql : 执行的sql语句
* @return {promise}
*/
function getOne(sql) {
return new Promise((resolve, reject) => {
con.query(sql, (err, data) => {
if (err) reject(err)
// data是一个数组
// if (data.length != 0) {
// // 查询到了数据
// resolve(data[0])
// } else {
// resolve(null)
// }
data.length != 0 ? resolve(data[0]) : resolve(null)
})
})
}
增、删、改、查
/**
* 增、删、改、查
* @param {string} sql : 执行的sql语句
* @return {promise}
*/
function exec(sql) {
return new Promise((resolve, reject) => {
con.query(sql, (err, data) => {
if (err) {
reject(err.message)
}
resolve(data)
})
})
}
向外导出这三个方法
//导出三个方法
module.exports = { getAll, getOne, exec }
设置users路由
写一下users路由,在routers文件下创建users.js作为用户的路由
设置路由时应导入db编写的方法
const { getAll, getOne, exec } = require("../db")
再导入express包,并实例化express
//导入express包
var express = require("express")
// 实例化express
var router = express.Router()
//导入三个方法
const { getAll, getOne, exec } = require("../db")
补充知识async/await
async/await是什么?
async/await 是ES7提出的基于Promise的解决异步的最终方案。
async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。因此对async函数可以直接then,返回值就是then方法传入的函数。
// async基础语法
async function fun0(){
console.log(1);
return 1;
}
fun0().then(val=>{
console.log(val) // 1,1
})
async function fun1(){
console.log('Promise');
return new Promise(function(resolve,reject){
resolve('Promise')
})
}
fun1().then(val => {
console.log(val); // Promise Promise
})
await
await 也是一个修饰符,只能放在async定义的函数内。可以理解为等待。
await 修饰的如果是Promise对象:可以获取Promise中返回的内容(resolve或reject的参数),且取到值后语句才会往下执行;
如果不是Promise对象:把这个非promise的东西当做await表达式的结果。
async function fun(){
let a = await 1;
let b = await new Promise((resolve,reject)=>{
setTimeout(function(){
resolve('setTimeout')
},3000)
})
let c = await function(){
return 'function'
}()
console.log(a,b,c)
}
fun(); // 3秒后输出: 1 "setTimeout" "function"
function log(time){
setTimeout(function(){
console.log(time);
return 1;
},time)
}
async function fun(){
let a = await log(1000);
let b = await log(3000);
let c = log(2000);
console.log(a);
console.log(1)
}
fun();
// 立即输出 undefined 1
// 1秒后输出 1000
// 2秒后输出 2000
// 3秒后输出 3000
async/await 的正确用法
// 使用async/await获取成功的结果
// 定义一个异步函数,3秒后才能获取到值(类似操作数据库)
function getSomeThing(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('获取成功')
},3000)
})
}
async function test(){
let a = await getSomeThing();
console.log(a)
}
test(); // 3秒后输出:获取成功
注意!
async可以单独使用,而await必须配合async使用,不然会报错。
实现获取所有用户
// GET /users?page=1&size=2
router.get("/", async function (req, res) {
//解析请求参数
const { page = 1, size = 5 } = req.query
let sql = `select count(*) as tobal from xzd_users`
let { total } = await getOne(sql)
//偏移量=(page-1)*size
let offset = (page - 1) * size
//操作数据库
sql = `select * from xzd_users limit ${offset},${size}`
const data = await getAll(sql)
res.send({
code: 0,
message: "获取用户成功",
result: {
total,
data,
},
})
})
测试
@baseURL= http://localhost:3000
### 获取所有用户
GET {{baseURL}}/users
![后端express集成nodemon项目搭建环境_sql_09](//dev-img.mos.moduyun.com/20231020/42d4be7b-a12c-45ba-8d78-73b5325169ba.png)
获取单个用户
//GET /users/:id
router.get("/:id", async (req, res) => {
const { id } = req.params
let sql = `select * from xzd_users where id=${id}`
const data = await getOne(sql)
res.send({
code: 0,
message: "获取单个用户成功",
result: data,
})
})
测试
@baseURL= http://localhost:3000
### 获取所有用户
GET {{baseURL}}/users
### 获取单个用户
GET {{baseURL}}/users/1
![后端express集成nodemon项目搭建环境_mysql_10](//dev-img.mos.moduyun.com/20231020/a443c719-d7a1-40e6-93dd-e886414cc5ed.png)
添加用户
//添加用户
// POST /users {username: 'xiaoming', password: '123456'}
router.post("/", async (req, res) => {
const { username, password } = req.body
let sql = `insert into xzd_users (username,password) values ('${username}','${password}')`
const { insertId } = await exec(sql)
res.send({
code: 0,
message: "添加用户成功",
result: {
id: insertId,
username,
password,
},
})
})
测试
### 添加用户
POST {{baseURL}}/users
Content-Type: application/json
{
"username":"银谷",
"password":12345
}
![后端express集成nodemon项目搭建环境_sql_11](//dev-img.mos.moduyun.com/20231020/2e17e5c8-6eb6-4838-9513-9f70f06b0272.png)
删除用户
//删除
// DELETE /todos?completed=1
router.delete("/:id", async (req, res) => {
// 一. 解析请求参数
const { id } = req.params
// 二. 操作数据库
let sql = `delete from xzd_users where id=${id}`
await exec(sql)
res.send({
code: 0,
message: "删除用户成功",
result: "",
})
})
// DELETE /todos?completed=1
router.delete("/", async (req, res) => {
// 一. 解析请求参数
const { id } = req.query
// 二. 操作数据库
let sql = `delete from xzd_users where id=${id}`
await exec(sql)
res.send({
code: 0,
message: "清理用户成功",
result: "",
})
})
测试
### 删除用户
DELETE {{baseURL}}/users/5
![后端express集成nodemon项目搭建环境_express_12](//dev-img.mos.moduyun.com/20231020/2becb2bb-92aa-4ac8-83c0-1fbcbdaa956f.png)
修改用户
//修改用户
// PUT /todos/1 {content: 'test-new'} 返回(修改的数据) {}
router.put("/:id", async (req, res) => {
//一、解析请求参数
const { id } = req.params
const { username, password } = req.body
//二、操作数据库
let sql = `update xzd_users set username='${username}',password='${password}' where id=${id}`
await exec(sql)
//三、返回结果
res.send({
code: 0,
message: "修改代办成功",
result: {
id,
username,
password,
},
})
})
测试
### 修改用户
PUT {{baseURL}}/users/1
Content-Type: application/json
{
"username":"银谷",
"password":1234566
}
![后端express集成nodemon项目搭建环境_express_13](//dev-img.mos.moduyun.com/20231020/95d1c181-c19c-44f5-b75b-1ba57edf378f.png)