持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
概述
今天我们使用 Node.js + Express + Sequelize + MySQL, 构建一个后端服务,来详细的介绍下 通过 Nodejs 与数据库的通讯。
创建项目
后端部分我们使用 Nodejs + Express + MySQL,的方式来构建。开始前需要准备 nodejs 环境,MySQL 数据库环境。
首先我们新建一个文件夹
mdkir nodejs-express-sequelize-mysql
cd nodejs-express-sequelize-mysql
然后在文件根目录初始化项目
npm init --yes
控制台输出如下内容
Wrote to /Users/handeqin/space/nodejs-express-sequelize-mysql/package.json:
{
"name": "nodejs-express-sequelize-mysql",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
初始化完成后,我们来添加项目中需要的模块
pnpm install express sequelize mysql2 body-parser cors --save
配置 Express Web 服务器
在根目录, 创建一个新的 app.js 文件,添加如下内容
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const app = express();
var corsOptions = {
origin: "*"
};
app.use(cors(corsOptions));
// content-type:application/json
app.use(bodyParser.json());
// content-type:application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// 简单路由
app.get("/", (req, res) => {
res.json({ message: "欢迎访问知见秋后端服务器" });
});
// 设置监听端口
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`服务器运行端口: ${PORT}.`);
});
- 在这个文件我们首先导入了
express,body-parse和cors模块 - `express 主要用于构建 Rest API 帮助前后端实现通讯
body-parse用于解析请求并创建req.body对象cors提供Express中间件corsOptions这里设置了可访问后端来源为*,意味着任何前端都可以和当前后端进行通讯,这样设置是不安全的,不过暂时为了避免跨域问题,先这样设置,之后再做处理- 后端服务在 8080 端口上监听
我们值终端执行 node app.js
可以看到输出了
服务器运行端口: 8080.
接着在浏览器输入 localhost:8080,就可以看到欢迎信息了,这说明我们的项目已经正常启动了
使用 Sequelize 连接数据库
Sequelize 是一个基于 Promise 的 Nodejs ORM, 目前支持 Postgres、MySQL、SQLite 和 Microsoft SQL Server。 它是一个很成熟的框架,有很好的性能和速度。
我们先来配置 Sequelize, 在根目录新建 app 文件夹,然后在建一个 config 文件夹,
src/app/config/db.config.js
module.exports = {
HOST: "192.168.1.5",
USER: "zhijianqiu",
PASSWORD: "123456",
DB: "demo",
port:3306,
dialect: "mysql",
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
};
HOST这里是你的 MySQL 服务器地址,如果数据库跑在本地就是loaclhost,如果在腾讯云等云服务上,就填写云服务给你的数据库地址,比如cdb-5nvdsixo.bj.tencentcdb.com这是腾讯云的数据库地址样式。USER数据库登录用户名PASSWORD用户名对应的登录密码DB数据库名称port数据库远程访问端口max最大连接数min最小连接数acquire超时时间idle空闲时间
初始化 Sequelize
新建一个文件 app/models/index.js,
const dbConfig = require("../config/db.config.js");
const Sequelize = require("sequelize");
const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
host: dbConfig.HOST,
dialect: dbConfig.dialect,
operatorsAliases: false,
pool: {
max: dbConfig.pool.max,
min: dbConfig.pool.min,
acquire: dbConfig.pool.acquire,
idle: dbConfig.pool.idle
}
});
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;
db.todos = require("./todo.model.js")(sequelize, Sequelize);
module.exports = db;
这里的todo.model.js 是一个用来操作数据库的 sequelize 模型,用于前端发出指令,后端接受指令后操作数据库,后文会具体讲解。
接着在根目录下的 app.js 文件最后添加 sync() 调用的方法
const db = require("./app/models");
db.sequelize.sync();
定义 Sequelize Model
在 models 文件夹中,创建 todoModel.js 文件
module.exports = (sequelize, Sequelize) => {
const Todo = sequelize.define("todo", {
title: {
type: Sequelize.STRING
},
description: {
type: Sequelize.STRING
},
status: {
type: Sequelize.BOOLEAN
}
});
return Todo;
};
Sequelize Model 是向 MySQL 中指定数据库的写入列,这里会自动生成 ID,title,description,status,createdAt,updatedAt 这六个列
初始化 Sequelize 之后,我们不需要在写任何增删改查函数,直接调就可以了。
- 创建一个新清单:
create(object) - 通过 id 查找清单:
findByPk(id) - 获取所有待办清单:
findAll() - 根据 ID 更新清单:
(data, where: { id: id }) - 根据 ID 删除清单:
destroy(where: { id: id }) - 删除所有清单:
destroy(where: {}) - 在所有清单中按标题查找:
findAll({ where: { title: ... } })
是不是超级方便,这些函数,我们会在接下来创建的「控制器」中使用。
创建控制器(controllers)
在 app/controllers/todoController.js 文件中,把上面 Sequelize 写入控制器来操作数据
const db = require("../models");
const Todo = db.todos;
const Op = db.Sequelize.Op;
// 创建并保存一条清单
exports.create = (req, res) => {
// Validate request
if (!req.body.title) {
res.status(400).send({
message: "内容不能为空"
});
return;
}
// 创建一条清单
const todo = {
title: req.body.title,
description: req.body.description,
stauts: req.body.stauts ? req.body.stauts : false
};
// 将清单保存到数据库
Todo.create(todo)
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "创建清单是发生错误。"
});
});
};
// 从数据库中搜索.
exports.findAll = (req, res) => {
const title = req.query.title;
var condition = title ? { title: { [Op.like]: `%${title}%` } } : null;
Todo.findAll({ where: condition })
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "搜索时,发生错误。"
});
});
};
// 按照条目 ID 搜索
exports.findOne = (req, res) => {
const id = req.params.id;
Todo.findByPk(id)
.then(data => {
if (data) {
res.send(data);
} else {
res.status(404).send({
message: `没有找到 ${id} 的清单`
});
}
})
.catch(err => {
res.status(500).send({
message: `查询第 ${id} 条清单时出错`
});
});
};
// 更新指定 ID 清单
exports.update = (req, res) => {
const id = req.params.id;
Todo.update(req.body, {
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "更新成功"
});
} else {
res.send({
message: `第 ${id} 条更新失败。`
});
}
})
.catch(err => {
res.status(500).send({
message: `更新第 ${id} 条清单时出错`
});
});
};
// Delete a Todo with the specified id in the request
exports.delete = (req, res) => {
const id = req.params.id;
Todo.destroy({
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "删除成功"
});
} else {
res.send({
message: `删除第${id}条清单失败。`
});
}
})
.catch(err => {
res.status(500).send({
message: "不能删除清单:" + id
});
});
};
// 删除数据库中所有清单
exports.deleteAll = (req, res) => {
Todo.destroy({
where: {},
truncate: false
})
.then(nums => {
res.send({ message: `删除${nums}条清单 ` });
})
.catch(err => {
res.status(500).send({
message:
err.message || "删除所有清单时出错"
});
});
};
// 检查所有清单状态
exports.findAllstauts = (req, res) => {
Todo.findAll({ where: { stauts: true } })
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "搜索清单时出错"
});
});
};
至此,整个后端部分就搭建完成了,我们把后端运行起来看看效果。
运行 Node.js Express 服务器
在 node.js 服务器根目录,运行 node app.js, ok 项目运行正常