node.js + express + mysql 简单运用
主要是学习下如何简单得运用,自己可以写出一个后台
目录
- 初始化一个项目
- 创建web服务
- get请求
- post put delete 三个请求
- 引入ejs 模板
- 中间件
- cookie
- session
- 路由模块化
- 官方推荐应用程序生成器(创建项目得脚手架)
- 图片上传 multer
- mysql 运用(案例)
- 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 简单运用相关推荐
- 跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-李宁-专题视频课程...
跟李宁老师做项目:小程序版网上商城(Node.js + Express + MySQL)-8799人已学习 课程介绍 本课程采用的技术包括小程序开发.Node.js.Express和M ...
- 如何高效快速地在Linux系统上部署Node.js+Express+MySQL的开发环境(桌面可视化)...
一.前言 可能一些初级前端和我一样,在有些项目需要前后台都一个人打通搞定的时候,对于后台和开发环境的部署还是比较头疼的.特别是Linux系统,由于没有系统接触过,也不太喜欢去记背那么多命令,大部分命令 ...
- 基于Node.js+Express+MySQL的爱心助农电商管理系统的设计与实现(附源码)
摘要 2020年新型冠状病毒突如其来,在疫情的影响下,全国各个地区的农产品销售均不同程度的出现了需求信息不畅,农产品管理困难,订单物流模糊,农产品滞销等问题的出现.与此同时2020年也是我国全面小康, ...
- node.js+express实现简单的增删改查
主要用node.js和express实现数据的增删改查 一:安装包 需要的包如图所示: "dependencies": {"art-template": &qu ...
- Node.js+express+MySQL仿美团注册登录绑定第三方登录
原文连接 准备 在开始做这个前,希望你已经配置好的Node,express和MySQL的开发环境.也可以参考参考文章 开发环境的配置 新建项目 参考Mac下express的安装和新建项目 mysql模 ...
- 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 ...
- node.js连接MySQL操作及注意事项
node.js作为服务端的js运行环境已经出现了有几年了,最近我有个朋友也在做这方面的开发,但是也是刚刚接触,遇到了很多坑.前几天他们在操作数据库的时候出现了点问题,后来我们一起看了看,其实都是nod ...
- Node.js 连接 MySQL 并进行数据库操作 –node.js 开发指南
Node.js是一套用来编写高性能网络服务器的JavaScript工具包 通常在NodeJS开发中我们经常涉及到操作数据库,尤其是 MySQL ,作为应用最为广泛的开源数据库则成为我们的首选,本篇就来 ...
- node.js + express 初体验【hello world】
[node.js] 一个神奇的XX 呵呵 :) 不知道怎么形容他才好! [express] 是node.js 开发web应用程序的框架 开发环境:XP 大家共同进步吧 :) 一:前期准备: ...
最新文章
- signature验证/salt验证/token验证的作用
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
- POJ 2492 A Bug's Life 带权并查集
- WinCE6.0的极速启动
- Hive--优化参数
- 华为平板解锁工具_2020年备战考研必选8款平板电脑 平板电脑推荐(12月最新版)...
- 错误: 找不到或无法加载主类 com.leyou.LeyouItemApplication Process finished with exit code 1...
- java 过滤脚本_我写的得到天气的Java代码,其中有过滤脚本和过滤HTMLtag的函数。...
- Tapestry 教程(七)在Tapestry中一起使用Hibernate
- 云计算十字真言及其在小博无线的实践
- DSP 2812: 使用C++封装外设时钟控制
- 将自己开发的vue组件库发布到npm
- Android DataBing基础使用 +ViewModel 及setvalue过程及原理
- 如何删除Word中的边框线
- 【Office使用技巧】word内公式相关快捷键
- java里面获取map的key和value的方法
- 还在为美容护肤问题焦虑吗?不妨试试红光光浴#大健康#红光光浴#红光#种光光学
- install - graph-tool
- 为什么使用计算机辅助翻译工具中文译文,TCloud计算机辅助翻译工具
- 数学模型:优化模型(二)血管分支问题
热门文章
- 计算机开机黑屏并有报警声,开机报警5声,开机黑屏报警8声
- matlab-粒子群源码优化模糊隶属度函数值
- UE4 Matinee制作相机动画及其蓝图播放(UE4.11和UE4.19测试通过)
- 新媒体运营:内容运营的核心与技巧
- c++中bitset的用法总结
- Gym - 101485G NWERC2015 G Guessing Camels
- [转].native的作用
- Qt5.9.0下载与安装(windows版本)
- 什么是 “零” 拷贝?
- 超入门级-基于中值滤波处理ECG信号的基线漂移-Python-MIT-BIH数据集