nodejs + express + mysql + redis 基础功能实现
nodejs + express + mysql + redis 基础功能实现
本文大体介绍了nodejs项目的创建、express框架的使用、mysql数据库的连接、以及redis的数据交互等方法,并举例了些简单的例子进行说明,代码都是亲自重头跑了一遍的,拿来可用。
一、创建nodejs 项目
1. 创建一个文件夹,以node_demo 为例,运用cmd 进入该文件夹,输入指令初始化项目
npm init -y
生成package.json 文件
可先安装以下包,后面会用到
2. nodejs 启动服务测试
创建server.js 文件,以hellow word! 为例做测试
本人用的 vscode,敲node 发现没代码提示,敲着有点不得劲。(不过一个个字母敲出来有助于记忆,有闲情的可以试试。)于是先去搞个代码提示插件。
打开vscode 终端控制台,安装 @types
npm i @types/node --save-dev
好了,现在有提示了
直接上代码
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'Text/plain'
});
res.end('hellow word!');
}).listen(3307, () => {
console.log('服务启动');
})
浏览器中输入 localhost:3307
出现 hellow word! 一个简单的服务就写好了
3. 运用express框架写接口
以get 接口 /testGet,post接口/testPost 为例,server.js代码如下
const express = require('express');
const app = express();
app.use(express.json()); // 解析json请求
app.use(express.urlencoded({extended: false})) // 解析URL-encoded请求
app.listen(3307, () => {
console.log('服务启动');
})
app.get('/testGet', (req, res) => { // 测试get 请求
returnParams(req.query, res)
})
app.post('/testPost', (req, res) => { // 测试post 请求
returnParams(req.body, res)
})
function returnParams(data, res) {
res.json({ code: 1, status: 'S', data: data, msg: '成功' })
}
打开 postman,调用接口测试
get 接口测试返回如下,可见testGet 接口拿到参数且成功返回
post 接口测试返回如下,可见testPost 接口也成功返回
注:post 请求时,json 格式需调用express.json中间件,表单格式需调用express.urlencoded 中间件
app.use(express.json()); // 解析json请求
app.use(express.urlencoded({extended: false})) // 解析URL-encoded请求
有时我们在调用相应的接口前需要做相应的拦截判断,此时可使用以下代码
app.all('*', (req, res, next) => {
// 写入相应的拦截操作
next(); // 要继续往下跑记得写上 next()
})
4. 热加载 与 跨域
写到这里你应该会发现,每改一次文件,你都需重新node server.js 一次,非常麻烦,于是这里使用hotnode 热加载,每保存一次,它将自动重新加载服务。
npm i hotnode --save
然后使用 hotnode server.js 启动node 即可。
若觉得该命令太长懒得写,也可在package.json 文件做如下配置
如此一来,使用 npm start 即可,但这样会有如下报错
根据网上查到的方法,print 为打印方法,既然程序没找到,那么干脆把它改为 console.log 方法。
打开hotloader.js 文件,找到相应位置,改为如下代码
this.process.stdout.on("data", function(data) {
return console.log(data.toString());
// return util.print(data.toString());
});
然后使用 npm start 运行就正常了
跨域问题
A. 可以使用现有轮子
npm i cors --save
const cors = require("cors")
app.use(cors()) // 解决跨域
B. 也可以用如下代码设置
//设置跨域访问
app.all('*', (req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1');
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
5. express router
以上虽然实现了接口的编写,但为了方便管理接口、区分功能模块,我们使用router 来划分下。
首先创建routes 文件夹,假设有一个“测试”模块,那么在routes 文件夹下创建test.js 文件
test.js 文件代码如下
const express = require('express');
const router = express.Router();
router.get('/testGet', (req, res) => { // 测试get 请求
returnParams(req.query, res)
})
router.post('/testPost', (req, res) => { // 测试post 请求
returnParams(req.body, res)
})
function returnParams(data, res) {
res.json({ code: 1, status: 'S', data: data, msg: '成功' })
}
module.exports = router
则 server.js 文件代码更改如下
const express = require('express');
const app = express();
const test = require('./routes/test');
app.use(express.json()); // 解析json请求
app.use(express.urlencoded({extended: false})) // 解析URL-encoded请求
app.listen(3307, () => {
console.log('服务启动');
})
app.all('*', (req, res, next) => {
// 写入相应的拦截操作
next(); // 要继续往下跑记得写上 next()
})
app.use('/test', test);
二、使用 sequelize 操作mysql 数据库
1. 开发准备
先下载安装mysql数据库,然后安装navicat 操作数据库,这里不过多说明,可自行百度。
以建好的表article 为例
项目中先安装 mysql、mysql2、sequelize 包
npm i mysql mysql2 sequelize --save
2. 连接数据库,建立模型
新建database 文件夹,在文件夹下新建db.js文件,写入代码如下
const Sequelize = require("sequelize");
const db = {}
const sequelize = new Sequelize('my_website', 'root', '123456', {
host: 'localhost',
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 3000,
idle: 10000,
}
});
db.sequelize = sequelize
db.Sequelize = Sequelize
module.exports = db;
这里可参照官方文档
然后建立模型
新建文件夹models,在文件夹下新建 Article.js 文件,写入代码如下(字段与数据库字段对应)
const Sequelize = require("sequelize");
const db = require("../database/db");
module.exports = db.sequelize.define('article', {
aid: {
type: Sequelize.INTEGER,
primaryKey: true, // 主键
},
title: {
type: Sequelize.STRING,
},
title_map: {
type: Sequelize.STRING,
},
content: {
type: Sequelize.TEXT,
},
create_time: {
type: Sequelize.DATE,
},
agree_num: {
type: Sequelize.INTEGER,
},
disagree_num: {
type: Sequelize.INTEGER,
},
comments_num: {
type: Sequelize.INTEGER,
},
}, {
timestamps: false, // 不自动加上 createdAt 和 updatedAt
freezeTableName: true, // 强制表名称等于模型名称,不自动将模型名复数并将其用作表名
})
注:nodejs 连接数据库时,可能会报错,文章最下方“参考资料”中给出了两个常见问题解决链接
3. 查询文章列表接口
routes 文件夹下建立article.js 文件,代码如下
const express = require('express');
const router = express.Router();
const Article = require('../models/Article');
router.post('/searchArticle', (req, res) => {
Article.findAll().then(sqlRes => {
res.json({ code: 1, status: 'S', data: sqlRes, msg: '成功' })
}).catch(sqlError => {
res.json({ code: 0, status: 'E', data: sqlError, msg: sqlError })
})
})
module.exports = router;
回到server.js 文件引入article
const article = require('./routes/article');
app.use('/article', article);
启动服务,用postman做测试,查询article 表中的数据
可见已查询成功,那么查询表数据就实现了。其他的增、删、改等操作在此不过多赘述,有兴趣的可以去官网看看。
三、nodejs 操作redis
1. 开发准备
下载安装redis后,启动redis,启动成功界面如下
保留该窗口,另启一个窗口,redis安装文件夹目录下输入命令
redis-cli -h localhost -p 6379
项目中安装 redis 包
npm i redis --save
2. 编写代码
创建redis 文件夹
新建redisOptions.js 文件,代码如下
const options = {
host: 'localhost',
port: 6379,
// password: '', // 本人未设置密码,所以隐藏,若你设了密码,则输入密码
detect_buffers: true // 传入buffer 返回也是buffer 否则会转换成String
}
module.exports = options
新建redisConfig.js 文件,代码如下(想要用到什么redis 操作,可自行写入方法)
const redis = require('redis')
const redisOptions = require('./redisOptions')
const options = {
host: redisOptions.host,
port: redisOptions.port,
password: redisOptions.password,
detect_buffers: redisOptions.detect_buffers, // 传入buffer 返回也是buffer 否则会转换成String
retry_strategy: function (options) {
// 重连机制
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
}
}
// 生成redis的client
const client = redis.createClient(options)
// 存储值
const setValue = (key, value) => {
if (typeof value === 'string') {
client.set(key, value)
} else if (typeof value === 'object') {
for (let item in value) {
client.hmset(key, item, value[item], redis.print)
}
}
}
// 数值自增
const incrValue = (key, value) => {
client.incr(key, value)
}
// 获取string
const getValue = (key) => {
return new Promise((resolve, reject) => {
client.get(key, (err, res) => {
if (err) {
reject(err)
} else {
resolve(res)
}
})
})
}
// 获取hash
const getHValue = (key) => {
return new Promise((resolve, reject) => {
client.hgetall(key, function (err, value) {
if (err) {
reject(err)
} else {
resolve(value)
}
})
})
}
// 导出
module.exports = {
setValue,
incrValue,
getValue,
getHValue
}
回到 test.js 文件,写入如下代码测试
const redis = require('../redis/redisConfig');
redis.setValue('testKey', 'testValue');
在命令行窗口中输入get testKey,发现值成功返回
nodejs 获取redis 值则使用 redis.getValue()
redis.getValue('testKey').then(val => {
console.log('val:', val);
})
到此,nodejs 基本功能差不多算说完了,最终目录结构如下
##### 废话star (可跳过)
本文主要是借鉴他人文章整合而成,在此特做说明,借鉴资料出处文后有说明。
写此文目的有三:
1. 梳理下知识以便更好的记忆;
2. 整合起来方便阅读,避免东查一点功能、西查一点功能,节省时间。方便自学者学习,也方便本人复制黏贴;
3. 以往都是复制别人的代码,拿别人的知识,现在怎么说也由小白晋级菜鸟了,也输出下知识做点回馈吧。
另:本人nodejs 用的较少,受限于眼界与项目经验,多有不足之处还望指正,有更优的方案或思路也望不吝赐教,感谢。
第一次写文,啰嗦了点,咳咳,
##### 废话end