主要是学习下如何简单得运用,自己可以写出一个后台

目录

  1. 初始化一个项目
  2. 创建web服务
  3. get请求
  4. post put delete 三个请求
  5. 引入ejs 模板
  6. 中间件
  7. cookie
  8. session
  9. 路由模块化
  10. 官方推荐应用程序生成器(创建项目得脚手架)
  11. 图片上传 multer
  12. mysql 运用(案例)
  13. mysql事务

1.初始化一个项目

1.安装Node.js
2新建一个文件夹,初始化项目 npm init
3.npm install express --save 安装express
4.新建一个index.js

2.创建web服务

index.js 内容
var express = require("express");
app.get("/", (req, res) => {// 使用ejsres.send("hello 默认");
});
app.listen(3000);

启动 node index.js

3.get请求

//浏览器直接打开
app.get("/login", (req, res) => {//参数传值  怎么取  req.queryres.send("hello 默认");
});
app.get("/news/getNews/:id", (req, res) => {// 动态路由var id = req.params["id"];res.send("获取 新闻" + id);
});

4.post put delete 三个请求

不能直接浏览器打开,可以通过psotman来测试(post put delete差不多写法)

app.post("/news/postNews", (req, res) => {// 动态路由res.send("增加 新闻");
});


5.引入ejs 模板

这种基本用于一些比较老得项目,前后端不分离得。ejs 有兴趣得可以取单独学学,express本身就自带了ejs,所以直接安装ejs后,直接用

直接使用ejs
1.先安装ejs
2.app.set(“view engine”, “ejs”)
3.默认为当前目录下得views文件夹,所以新建views
4.创建一个index.ejs

使用html ejs模板
1.先安装ejs
2.var ejs = require(“ejs”);
3.app.engine(“html”, ejs.__express);
4.app.set(“view engine”, “html”);
5.默认为当前目录下得views文件夹,所以新建views
6.创建一个index.html

ejs内容
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><h2>这是一个EJS的动态模板</h2><h5><%=message%></h5><form action="./submitData" method="post">用户名:<input type="text" value="yangjie" name="username"><br>密码<input type="password" value="123" name="password"><br><button type="submit">提交</button></form>
</body></html>
app.set("view engine", "ejs")
app.get("/login", (req, res) => {res.render("index", {message: "666",});// res.send("hello 登录");
});


6.中间件
应用级中间件:所有得匹配路由前都会调用这个中间件(用于权限判断)

app.use((req, res, next) => {console.log("应用级中间件");next();
});

路由级中间件(用得比较少) 为了能news/add能继续执行下去

app.get("/news/add", (req, res, next) => {// res.send("获取 新闻" + id);next();
});
app.get("/news/:id", (req, res) => {// 动态路由res.send("获取 新闻" + id);
});

内置中间件 访问static文件夹 得静态资源(不是路由)

app.use(express.static("static"));

第三方中间件 (很多 比如获取post传参得中间件)

安装body-parser

// 第三方中间件 (很多 比如获取post传参得中间件)
var bodyParser = require("body-parser");
// create application/json parser
var jsonParser = bodyParser.json();// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.post("/add", jsonParser, (req, res) => {// 动态路由console.log("参数:" + req.query.name);console.log("参数:" + req.body);res.send("第三方中间件");
});

错误处理中间件(用于路由匹配完成) 匹配不到

app.use((req, res, next) => {console.log("错误处理");res.status(404).send("404");
});

7.cookie
浏览器得缓存——cookie

特点:
1.大小4k左右
2.与服务端交互
3.可以设置时效性
4.方法需要自己封装
5.cookie数量20个得限制

1.安装npm i cookie-parser -s
2.const cookieParser = require(“cookie-parser”);
3.app.use(cookieParser());

app.get("/", (req, res) => {// 使用ejs// 存username 60秒后过期  获取方式 req.cookies.username  maxAge:多少毫秒之后失效  path:"/aaa"//  限制只能在哪个路由下访问  domain:".jd.com"  这样就可以多域名共享  比如 www.jd.com  aaa.jd.com等res.cookie("username", "张三", { maxAge: 1000 * 60 });// cookie加密 // 1.app.use(cookieParser("asdasd"));// 2.res.cookie("username", "张三", { maxAge: 1000 * 60,signed:true });// 3.获取 req.signedCookiesres.send("hello 默认");
});

8.session

1.安装npm install express-session -s
2.使用

// 设置session 基于 cookie
const session = require("express-session");
app.use(session({secret: "keyboard cat", //服务端生成得session签名name: "aaa", //修改session对应得cookie名resave: false, //强制保存,即使它没有变化saveUninitialized: true, //强制将未初始化得session 存储cookie: {secure: false, //true只有Https协议才能访问cookiemaxAge: 1000 * 60,},// rolling: true,  //重新设置过期时间})
);
app.get("/", (req, res) => {req.session.username = "杨接";req.session.name = "杨接111";console.log(req.session.username);console.log(req.session.name);res.send("hello 默认");
});

session存储到mysql

npm i mysql -s
npm i express-mysql-session -s

var mysql = require("mysql");
const session = require("express-session");
var MySQLStore = require("express-mysql-session")(session);
var option = {host: "localhost",user: "root",password: "123456",database: "session",    //数据库名
};
var connection = mysql.createConnection(option);
// session存储mysql
var sessionStore = new MySQLStore({expiration: 10800000,createDatabaseTable: true, //是否创建表schema: {tableName: "session_tab", //表名columnNames: {//列选项session_id: "session_id",expires: "expires",data: "data",},},},connection
);connection.connect();

app.listen(80); 可以省略端口号
效果

9.路由模块化

1,上面代码中得一些中间件 改变写法 例如

// create application/json parser
app.use(bodyParser.json());
// create application/x-www-form-urlencoded parser
app.use(bodyParser.urlencoded({ extended: false }));

2.创建 两个js

login.js  news 也差不多
var express = require("express");
var router = express.Router("express");router.get("/", (req, res) => {// 设置req.session.username = "杨接";req.session.name = "杨接111";// 获取console.log(req.session.username);console.log(req.session.name);// 销毁// 1.req.session.cookie.maxAge=0 所有都销毁// 2.req.session.username=""  销毁指定得值// 3.req.session.destroy()res.send("hello 默认");
});
// 使用ejs 先安装ejs 然后直接使用   app.set("view engine", "ejs"); express本身就封装了ejs
router.get("/login", (req, res) => {res.render("index", {message: "666",});// res.send("hello 登录");
});router.post("/doLogin", (req, res) => {// 获取参数传值var body = req.body;console.log(body);res.send("hello 登录");
});module.exports = router;

3.index.js中引入

const login = require("./routes/login");
const news = require("./routes/news");
// 挂载模块
app.use("/", login);
app.use("/news", news); //news.js中前缀/news要去掉

10,官方推荐应用程序生成器(创建项目得脚手架)

1.安装 npm i express-generator -g 全局安装
2.express -h 能查看 安装成功
3.express --view=pug 项目名称 (要提前cd到你要创建项目得目录)
4.运行bin 中得www.js

11.图片上传 multer
需求:上传文件(可以多个上传)根据日期自动生成文件夹(分类)

安装插件
1.npm i multer -s
2.npm i silly-datetime -s
3.npm i mkdirp -s // 这个是用来创建文件夹的

封装一个uploadFileService.js

/*** 文件上传* @returns {Promise<void>}*/
var path = require("path");
var multer = require("multer");
var sd = require("silly-datetime");
const mkdirp = require("mkdirp");
/**上传图片的方法调用 upload()是因为在别的地方调用来这个js 需要先执行upload()单张图片调用upload().single("avatar")  avatar 是input的name多张图片调用1.upload().array("avatar",12)  name为avatar最多12张2.upload().fields([{name:"avatar",maxCount:1},{name:"aa",maxCount:2}])
*/
var uploadFileService = {// 文件上传upload: () => {var storage = multer.diskStorage({// 配置上传目录destination: async (req, file, cb) => {// 1.获取当前日期let day = sd.format(new Date(), "YYYYMMDD");let dir = path.join("uploads/", day);// 2.按照日期生成目录  mkdirp 是异步方法,返回的是一个promise异步对象await mkdirp(dir);cb(null, dir);},// 修改文件名filename: (req, file, cb) => {// 获取后缀名// let extname = path.extname(file.originalname);let arr = file.originalname.split(".");cb(null, arr[0] + "-" + Date.now() + "." + arr[1]);},});var upload = multer({ storage: storage });return upload;},
};module.exports = uploadFileService;

表单提交

<form action="./doLogin" method="post" enctype="multipart/form-data">用户名:<input type="text" value="yangjie" name="username"><br>图片1:<input type="file" name="avatar" /><br>图片2:<input type="file" name="aaa" /><br>密码<input type="password" value="123" name="password"><br><button type="submit">提交</button></form>

/doLogin 路由

var { upload } = require("../util/uploadFileService");
var express = require("express");
var router = express.Router("express");
router.post("/doLogin",upload().fields([{ name: "avatar", maxCount: 1 },{ name: "aaa", maxCount: 1 },]),(req, res) => {// 获取参数传值var body = req.body;var file = req.file;console.log(body, file);res.send("执行 登录");}
);


12.mysql 运用
路由这里不配了,主要写下这里的增删改查(删除没弄)

/*** 用户注册* 1.发送验证码* 2.登录* 3.判断是否是第一次登录* 4.是的话 注册用户信息* 5.是的话 创建用户附表* 6.获取用户信息* @returns {Promise<void>}*/
var dbConfig = require("../util/dbconfig");
let codeArr = [];
/*------------------接口--------------------------*/
// 发送验证码
let sendCode = (req, res) => {// 获取手机号let phone = req.body.phone;let code = fourNum(1000, 9999);// 验证是否已发送let isSend = codeArr.some((item) => {return item.phone == phone;});if (isSend) {// 可以用阿里云 极光等短信服务res.send({data: {},resultCode: 1001,msg: "验证码已发送!",});} else {codeArr.push({code: code,phone: phone,});// 有效性setTimeout((re) => {codeArr = codeArr.filter((item) => {return item.phone != phone;});}, 60 * 1000 * 10);res.send({data: {code: code,phone: phone,},resultCode: 1,msg: "发送成功",});}
};// 验证码登录
let login1 = async (req, res) => {let { phone, code } = req.body;let arr = codeArr.filter((item) => {return item.phone == phone;});if (arr.length == 0 || arr[0].code != code) {res.send({data: {},resultCode: 1002,msg: "验证码错误!",});} else {let data = await phoneBind(phone);console.log("结束");res.send({data: data,resultCode: 1,msg: "登录成功!",});}
};// 修改用户信息接口
let saveInfo = async (req, res) => {let params = req.body;let { age, sex, school, user_id } = params;let sql = `update userinfo set age=?,sex=?,school=? where user_id=?`;let arr = [age, sex, school, user_id];let data = await dbConfig.asyncSqlConnect(sql, arr);if (data.affectedRows == 1) {let userInfo = await getUserInfo(user_id);userInfo[0].userInfo = await getUserInfoDetail(user_id);res.send({data: userInfo[0],resultCode: 1,msg: "登录成功!",});} else {res.send({data: null,resultCode: 1003,msg: "修改失败",});}
};// 删除用户信息接口
// 删除有多个关联表的时候需要用的事务,  多步操作的时候一旦出错 回滚,保护数据库
let deleteInfo = async (req, res) => {};/*------------------方法--------------------------*/// 判断用户是否注册
let phoneBind = async (phone) => {// 判断用户是否注册let sqlArr = [];let data = await dbConfig.asyncSqlConnect("select * from user where phone=" + phone + " or username=" + phone,sqlArr);let userInfo = {};if (data.length && data.length != 0) {data[0].userInfo = await getUserInfoDetail(data[0].id);console.log(data[0]);return data[0];} else {// 用户未注册,需要写入数据userInfo = await register(phone);userInfo[0].userInfo = await getUserInfoDetail(userInfo[0].id);return userInfo[0];}
};
// 用户注册
let register = async function (phone) {// 建立参数var sql = `insert into user (username,phone,create_time) values (?,?,?)`;var sqlArr = [phone, phone, timestampToTime(new Date().getTime())];// 调用连接池let data = await dbConfig.asyncSqlConnect(sql, sqlArr);// 添加数据成功与否判断if (data.affectedRows == 1) {// 执行成功 获取用户信息let info = await getUserInfo(phone);// 创建用户的附表(详情表)let userInfo = await createUserInfo(info[0].id, phone);return info;} else {return false;}
};
// 获取用户信息
let getUserInfo = (username) => {// 建立参数var sql = `select * from user where id=? or phone=? or username=?`;var sqlArr = [username, username, username];return dbConfig.asyncSqlConnect(sql, sqlArr);
};
// 创建用户附表
let createUserInfo = (user_id, phone) => {// 建立参数var sql = `insert into userinfo(user_id,name,phone) values (?,?,?)`;var sqlArr = [user_id, phone, phone];return dbConfig.asyncSqlConnect(sql, sqlArr);
};// 获取用户详情
let getUserInfoDetail = (user_id) => {// 建立参数var sql = `select name,age,phone,sex,school from userinfo where user_id=?`;var sqlArr = [user_id];console.log(user_id);return dbConfig.asyncSqlConnect(sql, sqlArr);
};// 随机生成四位数
function fourNum(min, max) {return Math.floor(Math.random() * (max - min)) + min;
}
function timestampToTime(timestamp) {var date = new Date(timestamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000var Y = date.getFullYear() + "-";var M =(date.getMonth() + 1 < 10? "0" + (date.getMonth() + 1): date.getMonth() + 1) + "-";var D = (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";var h =(date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";var m =(date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) +":";var s =date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();return Y + M + D + h + m + s;
}module.exports = { sendCode, login1, saveInfo };

连接池

const mysql = require("mysql");
module.exports = {// 基本配置config: {host: "localhost",user: "root",port: 3306,password: "123456",database: "students", //数据库名},// 连接数据库,使用mysql的连接池的方式// 连接池对象// 这里要用function 不要用es6 不然this指向有问题sqlConnect: function (sql, sqlArr, callBack) {var pool = mysql.createPool(this.config);pool.getConnection((err, conn) => {if (err) {console.log("连接失败", err);return;}// 事件驱动回调conn.query(sql, sqlArr, callBack);// 释放连接conn.release();});},// 异步回调asyncSqlConnect: function (sql, sqlArr) {return new Promise((resolve, reject) => {var pool = mysql.createPool(this.config);pool.getConnection((err, conn) => {if (err) {console.log("连接失败", err);reject(err);} else {//开启事务// conn.beginTransaction((err) => {//     if (err) {//         console.log("开启事务失败", err);//         reject(err);//     } else {// 事件驱动回调conn.query(sql, sqlArr, (err, data) => {if (err) {console.log("连接失败1", err);reject(err);} else {console.log("成功");resolve(data);}});// 释放连接conn.release();//     }// });}});});},
};

13.mysql事务
同时执行多条语句,一旦失败 回滚

封装的函数

const mysql = require("mysql");
var config = {host: "localhost",user: "root",port: 3306,password: "123456",database: "myself", //数据库名
};
var pool = mysql.createPool(config);
const execTransection = (sqlArr) => {return new Promise((resolve, reject) => {var promiseArr = [];pool.getConnection(function (err, connection) {if (err) {return reject(err);}connection.beginTransaction((err) => {if (err) {return reject("开启事务失败");}// 将所有需要执行的sql封装为数组promiseArr = sqlArr.map(({ sql, values }) => {return new Promise((resolve, reject) => {connection.query(sql, values, (e, rows, fields) => {e ? reject(e) : resolve(rows);});});});// Promise调用所有sql,一旦出错,回滚,否则,提交事务并释放链接Promise.all(promiseArr).then((res) => {connection.commit((error) => {if (error) {console.log("事务提交失败");reject(error);}});connection.release(); // 释放链接resolve(res);}).catch((err) => {connection.rollback(() => {console.log("数据操作回滚");});reject(err);});});});});
};
module.exports = execTransection;

使用

let resp = await dbConfig([{sql: "select * from subjecttype",values: [],},{sql: "select * from subjecttype",values: [],},]);ctx.body = {data: resp,// data: {//     list: resp,//     total: 0,// },resultCode: 1,msg: "获取成功!",};

node.js + express + mysql 简单运用相关推荐

  1. 跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-李宁-专题视频课程...

    跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-8799人已学习 课程介绍         本课程采用的技术包括小程序开发.Node.js.Express和M ...

  2. 如何高效快速地在Linux系统上部署Node.js+Express+MySQL的开发环境(桌面可视化)...

    一.前言 可能一些初级前端和我一样,在有些项目需要前后台都一个人打通搞定的时候,对于后台和开发环境的部署还是比较头疼的.特别是Linux系统,由于没有系统接触过,也不太喜欢去记背那么多命令,大部分命令 ...

  3. 基于Node.js+Express+MySQL的爱心助农电商管理系统的设计与实现(附源码)

    摘要 2020年新型冠状病毒突如其来,在疫情的影响下,全国各个地区的农产品销售均不同程度的出现了需求信息不畅,农产品管理困难,订单物流模糊,农产品滞销等问题的出现.与此同时2020年也是我国全面小康, ...

  4. node.js+express实现简单的增删改查

    主要用node.js和express实现数据的增删改查 一:安装包 需要的包如图所示: "dependencies": {"art-template": &qu ...

  5. Node.js+express+MySQL仿美团注册登录绑定第三方登录

    原文连接 准备 在开始做这个前,希望你已经配置好的Node,express和MySQL的开发环境.也可以参考参考文章 开发环境的配置 新建项目 参考Mac下express的安装和新建项目 mysql模 ...

  6. Node.js+Express+Vue+MySQL+axios的项目搭建

    1 基本搭建 创建vue项目之前需要先安装Node.js和MySQL数据库 1.1 vue脚手架安装 npm i vue -g npm i @vue/cli -g//初始化vue项目 vue crea ...

  7. node.js连接MySQL操作及注意事项

    node.js作为服务端的js运行环境已经出现了有几年了,最近我有个朋友也在做这方面的开发,但是也是刚刚接触,遇到了很多坑.前几天他们在操作数据库的时候出现了点问题,后来我们一起看了看,其实都是nod ...

  8. Node.js 连接 MySQL 并进行数据库操作 –node.js 开发指南

    Node.js是一套用来编写高性能网络服务器的JavaScript工具包 通常在NodeJS开发中我们经常涉及到操作数据库,尤其是 MySQL ,作为应用最为广泛的开源数据库则成为我们的首选,本篇就来 ...

  9. node.js + express 初体验【hello world】

    [node.js]  一个神奇的XX 呵呵 :) 不知道怎么形容他才好!  [express] 是node.js 开发web应用程序的框架  开发环境:XP 大家共同进步吧 :)  一:前期准备:  ...

最新文章

  1. signature验证/salt验证/token验证的作用
  2. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
  3. POJ 2492 A Bug's Life 带权并查集
  4. WinCE6.0的极速启动
  5. Hive--优化参数
  6. 华为平板解锁工具_2020年备战考研必选8款平板电脑 平板电脑推荐(12月最新版)...
  7. 错误: 找不到或无法加载主类 com.leyou.LeyouItemApplication Process finished with exit code 1...
  8. java 过滤脚本_我写的得到天气的Java代码,其中有过滤脚本和过滤HTMLtag的函数。...
  9. Tapestry 教程(七)在Tapestry中一起使用Hibernate
  10. 云计算十字真言及其在小博无线的实践
  11. DSP 2812: 使用C++封装外设时钟控制
  12. 将自己开发的vue组件库发布到npm
  13. Android DataBing基础使用 +ViewModel 及setvalue过程及原理
  14. 如何删除Word中的边框线
  15. 【Office使用技巧】word内公式相关快捷键
  16. java里面获取map的key和value的方法
  17. 还在为美容护肤问题焦虑吗?不妨试试红光光浴#大健康#红光光浴#红光#种光光学
  18. install - graph-tool
  19. 为什么使用计算机辅助翻译工具中文译文,TCloud计算机辅助翻译工具
  20. 数学模型:优化模型(二)血管分支问题

热门文章

  1. 计算机开机黑屏并有报警声,开机报警5声,开机黑屏报警8声
  2. matlab-粒子群源码优化模糊隶属度函数值
  3. UE4 Matinee制作相机动画及其蓝图播放(UE4.11和UE4.19测试通过)
  4. 新媒体运营:内容运营的核心与技巧
  5. c++中bitset的用法总结
  6. Gym - 101485G NWERC2015 G Guessing Camels
  7. [转].native的作用
  8. Qt5.9.0下载与安装(windows版本)
  9. 什么是 “零” 拷贝?
  10. 超入门级-基于中值滤波处理ECG信号的基线漂移-Python-MIT-BIH数据集