使用Node.js+Koa 从零开始写个人博客系统——后端部分(一)
创始人
2025-06-01 20:24:01
0

此项目始终贯彻在做实际项目中,学习新的知识,适合看不进去视频,或者官方文档的人阅读,
小白也能上手操作,大佬也能理清思路,话不多说上车!!

1.0 关于node.js

一心上手搓代码的可略过此概念

什么是Node.js?

Node.js是一个Javascript运行环境(runtime)。

优缺点如何?

优点:

1.事件驱动

2.异步编程

3.非阻塞模式的IO

4.轻量高效

缺点:

1.可靠性低

2.单进程,单线程,只支持单核cpu,不能充分的利用多核cpu服务器。一旦这个进程崩掉,那么整个web服务就崩掉了。

适用场景如何?

适用场景:

1.JSON APIL ——构建一个Rest/JSON API服务,node.js可以充分发挥其非堵塞IO模型以及javascript对JSON的功能支持

2.单页面、多Ajax请求应用——前端有大量的异步请求,需要服务器后端有极高的响应速度

3.基于node.js开发Unix命令行工具——node.js可以大量产生子进程,并以流的方式输出

4.流式数据——传统的web应用,通常会将HTTP 请求喝响应看成是原子事件。而node.js会充分利用流式数据这个特点,构建非常酷的应用

不适用场景:

cpu使用率较重、io使用率较轻的应用

1.1 创建Node.js项目

这一步的前提是你已经安装好Node.js环境了,没安装的简单安装下可以参照以下网站
https://www.runoob.com/nodejs/nodejs-install-setup.html

安装完毕后,我使用的工具是webstorm来写Nodejs项目,官网在这里
https://www.jetbrains.com/webstorm/

新建nodejs项目

在这里插入图片描述

新建以下的目录与文件
在这里插入图片描述

1.2 初步填充app.js文件

这里需要使用到两个东西

什么是Koa?

Koa 是一个使用 Node.js 的 web 开发框架,通过中间件的方式解决 web 开发中的 http 处理、业务逻辑实现。它提供 web 开发常见的各种基础功能
提供一套规范的编码方式,让开发者可以聚焦在业务逻辑实现,代码就可以在框架内按照预期执行。
​ 安装

安装Koa
npm install Koa

app.js中复制以下的代码

# 引入Koa
const Koa = require('koa');
# 创建Koa对象
const app = new Koa();
# 拦截任意访问链接
app.use(async ctx => {ctx.body = 'Hello World';
});
# 监听端口
app.listen(3000);

什么是Koa-router?

Koa-router 是 koa 的一个路由中间件,它可以将请求的URL和方法(如:GET 、 POST 、 PUT 、 DELETE 等) 匹配到对应的响应程序或页面。

在app.js中替换为以下代码

const Koa = require('koa');
const Router = require('koa-router')const app = new Koa();
const router = new Router()router.get('/hello', (ctx)=>{ctx.body= 'hello world!';
})// 注册路由
app.use(router.routes()).use(router.allowedMethods())app.listen(3000,() => {console.log('Hello World');
});

运行方法,鼠标右击,选择运行app.js文件即可
在这里插入图片描述

运行当前文件,得到 并访问
localhost:3000/hello

在这里插入图片描述

恭喜你已经完成了第一个简单的项目!!!

1.3 创建router中的文件

新建如下目录
在这里插入图片描述

article.js中复制以下代码

const Router = require("koa-router");const router=new Router({prefix:"/Admin"
});//模糊查询加分页获取文章数据
router.post("/getArticles",(x)=>{//post的请求参数console.log(x.request.body)
})
//新增文章
router.post("/addArticles",(x)=>{})//更新文章
router.post("/updateArticles",x=>{})//删除文章
router.post("/removeArticles",x=>{})//模糊查询加分页获取评论数据
router.post("/getCommentPage",x=>{})//删除评论
router.post("/removeComment",x=>{})//更新评论
router.post("/updateComment",x=>{})
module.exports = router
______________________________________________
login.js复制一下代码
-----------------
const Router=require("koa-router")
const router=new Router({prefix:'/Blog'
})
//开始登录
router.post("/Login",x=>{})
module.exports=router;--------------------------
article.js
--------------------------
const Router=require("koa-router")
const router=new Router({prefix:'/Blog'
})
//模糊查询加分页获取文章数据
router.post("/getPageData",x=>{})
//获取详细文章内容
router.get("/getArticles:title",x=>{console.log(x.request.body)
})
//根据时间线获取文章
router.get("/getArticlesByTimeLine",x=>{})
//获取文章通过指定搜索
router.get("/getArticlesSearch:search",x=>{})
module.exports = router
------------------------
friendlink.js
------------------------
const Router=require("koa-router")
const router=new Router({prefix:'/Blog'
})
//获取所有友情链接
router.get("/getAllLink",x=>{console.log(111)
})
module.exports=router
--------------------
message.js
-------------------
const Router=require("koa-router")
const router=new Router({prefix:'/Blog'
})
//获取所有留言
router.post("/getAllMessage",x=>{
})
module.exports=router;

prefix
koa-router提供一种router.prefix方法,此方法对于某一个router来说,是一个全局配置,此router的所有路径都会自动被添加该前缀。

1.4 创建新的index.js

在这里插入图片描述
复制以下的代码

const fs = require('fs')module.exports = (app) => {// 读取当前目录下所有文件fs.readdirSync(__dirname).forEach(file => {// 除去 `index.js` 文件外其他的都要注册到 `app` 中if (file === 'index.js')returnconst router = require(`./${file}`)console.log(router)app.use(router.routes()).use(router.allowedMethods())})
}

启动项目 浏览器访问

http://localhost:3000/Blog/getAllLink

控制台得到。
在这里插入图片描述

在这里插入图片描述

OK! 简单的路由也使用完毕了

1.5 新建控制器js文件

class Admincontroller{getArticles(x){console.log("这是控制器getArticles")return x.body="这是控制器getArticles!!!!!"}addArticles(x){return x.body="addArticles"}updateArticles(x){return x.body="updateArticles"}removeArticles(x){return x.body="removeArticles"}getCommentPage(x){return x.body="getCommentPage"}removeComment(x){return x.body="removeComment"}updateComment(x){return x.body="updateComment"}
}module.exports=new Admincontroller()----------
class Articlecontroller {getPageData(x) {return x.body = "getPageData"}getArticles(x) {return x.body = "getArticles"}getArticlesByTimeLine(x) {return x.body = "getArticlesByTimeLine"}getArticlesSearch(x) {return x.body = "getArticlesSearch"}
}module.exports=new Articlecontroller()-----------
class Friendlinkcontroller {getAllLink(x) {return x.body = "getAllLink"}
}module.exports=new Friendlinkcontroller()
--------------------
class Logincontroller {Login(x) {return x.body = "Login"}
}module.exports=new Logincontroller()-------------------------
class Messagecontroller {getAllMessage(x) {return x.body = "getAllMessage"}
}module.exports=new Messagecontroller()

这里我准备使用3层架构。所以才有了Controller层。

1.6 替换路由文件

在这里插入图片描述

------admin.js-----
const Router = require("koa-router");
const Controller=require("./../controller/admincontroller")
const router=new Router({prefix:"/Admin"
});//模糊查询加分页获取文章数据
router.post("/getArticles",Controller.getArticles)
//新增文章
router.post("/addArticles",Controller.addArticles)//更新文章
router.post("/updateArticles",Controller.updateArticles)//删除文章
router.post("/removeArticles",Controller.removeArticles)//模糊查询加分页获取评论数据
router.post("/getCommentPage",Controller.getCommentPage)//删除评论
router.post("/removeComment",Controller.removeComment)//更新评论
router.post("/updateComment",Controller.updateComment)
module.exports = router`---------------
const Router=require("koa-router")
const Controller=require("./../controller/articlecontroller")const router=new Router({prefix:'/Blog'
})
//模糊查询加分页获取文章数据
router.post("/getPageData",Controller.getPageData)
//获取详细文章内容
router.get("/getArticles:title",Controller.getArticles)
//根据时间线获取文章
router.get("/getArticlesByTimeLine",Controller.getArticlesByTimeLine)
//获取文章通过指定搜索
router.get("/getArticlesSearch:search",Controller.getArticlesSearch)
module.exports = router-------------
const Router=require("koa-router")
const Controller=require("./../controller/friendlinkcontroller")const router=new Router({prefix:'/Blog'
})//获取所有友情链接
router.get("/getAllLink",Controller.getAllLink)
module.exports=router----------------
const Router=require("koa-router")
const Controller=require("./../controller/messagecontroller")const router=new Router({prefix:'/Blog'
})
//获取所有留言
router.post("/getAllMessage",Controller.getAllMessage)
module.exports=router;--------------
const Router=require("koa-router")
const Controller=require("./../controller/logincontroller")
const router=new Router({prefix:'/Blog'
})
//开始登录
router.post("/Login",Controller.Login)
module.exports=router;

启动测试

http://localhost:3000/Blog/getAllLink

在这里插入图片描述

OK 控制器使用完毕了

2.1 使用sequelize

Sequelize是一个强大的jsORM框架,可快速操作数据库
官网
https://www.sequelize.cn/core-concepts/getting-started
安装

# 使用 npm
npm i sequelize # 这将安装最新版本的 Sequelizenpm i mysql2 # MySQL

并建立以下的文件
在这里插入图片描述

修改配置文件内容

module.exports = {environment: 'dev',database: {dbName: 'boblog_0321',host: 'localhost',port: 3306,user: 'root',password: 'xx'},
}

要想使用sequelize 这个ORM框架,则必须先建立数据库中各个表对应的Model
而建立model。是通过sequelize的define方法建立模型的,Model相当于数据库中的表,该对象不能通过构造函数实例化,而只能通过sequelize.define()或sequelize.import()方法创建。

简单使用

看下面的代码,这样就创建了一个简单的model(article_model),其中article_model对应数据库中的article表。其中article_summary是表中的一个字段,article_summary{}中写的都是当前字段的属性信息。
需要注意通过这种方式同步的表会在表名称后面添加一个s作为复数。同步数据库是会默认添加两个字段createdAt和updatedAt有的时候可能不需要这两个字段。这个时候需要在第三个字段中添加timestamps为false默认为true。

const ArticleModel = sequelize.define("article_model", {article_summary: {type: DataTypes.TEXT,allowNull: true,defaultValue: null,primaryKey: false,autoIncrement: false,comment: "摘要",field: "article_summary"}},{ tableName: "article",comment: "",indexes: [], timestamps:false});

上面可以看出通过Sequelize.STRING设置当前字段的类型,Sequelize提供了很多数据类型供我们进行使用:如下
在这里插入图片描述
但是这样一个个的建立太麻烦了,所以请看下面的

2.2 执行sql语句

xx看文章末尾

2.3使用sequelize-automate

我们开发时,是先创建表,然后再写业务代码。
而且我们的表结构不能轻易变更,变更表结构可能有单独的流程。
所以大部分情况下,我们都是根据表结构手动写 Models,而不能直接使用 sequelize.sync() 去更新表结构。
然而当表非常多的时候,手动写 Models 是一件非常繁琐的事情,并且都是低级的重复性的事情。显然这种事情应该交由工具来做,这个工具就是 sequelize-automate 。
官网:
https://github.com/nodejh/sequelize-automate

安装
npm install sequelize-automate --save
使用
找到package.json文件
在这里插入图片描述

替换scripts的代码块

  "scripts": {"test": "echo \"Error: no test specified\" && exit 1","sequelize-automate": "sequelize-automate"},

*** sequelize-automate 命令详解 ***
sequelize-automate 命令支持的参数主要有:

–type, -t 指定 models 代码风格,当前可选值:js ts egg midway
–dialect, -e 数据库类型,可选值:mysql sqlite postgres mssql mariadb
–host, -h 数据库 host
–database, -d 数据库名
–user, -u 数据库用户名
–password, -p 数据库密码
–port, -P 数据库端口,默认:MySQL/MariaDB 3306,Postgres 5432,SSQL: 1433
–output, -o 指定输出 models 文件的目录,默认会生成在当前目录下 models 文件夹中
–camel, -C models 文件中代码是否使用驼峰发命名,默认 false
–emptyDir, -r 是否清空 models 目录(即 -o 指定的目录),如果为 true,则生成 models 之前会清空对应目录,默认 false
–config, -c 指定配置文件,可以在一个配置文件中指定命令的参数

新建配置文件
在这里插入图片描述
复制以下内容
注意修改


module.exports = {dbOptions: {database: 'yyy',username: 'root',password: 'xx',dialect:"mysql",host: 'localhost',port: 3306},options: {type: "js",dir: "./app/entity"}
}

然后打开终端运行以下命令

sequelize-automate -c dbInit.js

等待执行完成可以看到
在这里插入图片描述
这样就是成功了。
修改冗余字段,选中entity鼠标右键选择如图所示
在这里插入图片描述
使用以下规则进行替换
indexes: []
indexes: [], timestamps:false
在这里插入图片描述
替换完成就OK了

2.5 更改config/dbconfig.js

module.exports = {dbOptions: {database: 'yyy',username: 'root',password: 'xx',dialect:"mysql",host: 'localhost',port: 3306},options: {type: "js",dir: "./app/entity"}
}

2.6 测试sequelize是否可以连接数据库

复制以下代码直到app.js中进行测试

const Conf = require("./config/dbconfig");const sequelize = new Sequelize(Conf.dbOptions.database, Conf.dbOptions.username, Conf.dbOptions.password, {host: Conf.dbOptions.host,dialect: Conf.dbOptions.dialect
});
try {sequelize.authenticate();console.log('Connection has been established successfully.');
} catch (error) {console.error('Unable to connect to the database:', error);
}

运行程序,如下即为成功!
在这里插入图片描述

2.7 使用增删改查

app.js中加入以下代码

const {Sequelize} = require("sequelize");
const Conf = require("./config/dbconfig");
const Ar=require("./app/entity/article")
const sequelize = new Sequelize(Conf.dbOptions.database, Conf.dbOptions.username, Conf.dbOptions.password, {host: Conf.dbOptions.host,dialect: Conf.dbOptions.dialect
});try {sequelize.authenticate();Ar(sequelize).findAll().then(x=>{console.log(x)})console.log('Connection has been established successfully.');
} catch (error) {console.error('Unable to connect to the database:', error);
}

2.8 抽离数据库连接代码至Core中

新建如下文件
在这里插入图片描述
DbConn.js中
复制这些

//创建数据库链接
const {Sequelize} = require("sequelize");
const Conf = require("../config/dbconfig");
module.exports=new Sequelize(Conf.dbOptions.database, Conf.dbOptions.username, Conf.dbOptions.password, {host: Conf.dbOptions.host,dialect: Conf.dbOptions.dialect
});

替换app.js中的代码为如下

const Koa = require('koa');
const Router = require('koa-router')
const MyRouter=require("./app/router/index");
const Ar=require("./app/entity/article")
const conn=require("./core/DBConn")const app = new Koa();
const router = new Router()MyRouter(app)//查询全部
Ar(conn).findAll().then(x=>{console.log(x)
})// 注册路由
app.use(router.routes()).use(router.allowedMethods())app.listen(3000,() => {console.log('Hello World');
});

相关内容

热门资讯

“锥刀之末”的意思 “锥刀之末”的意思 成语拼音: [zhuī dāo zhī mò] ...
“出神入化”的意思 “出神入化”的意思 成语拼音: [chū shén rù huà] ...
形容诗词的成语拼音与相应解释 形容诗词的成语拼音与相应解释  【提要】本篇《形容诗词的成语》由应届毕业生小编特别为需要成语古诗古文...
形容哭的的成语 形容哭的的成语  哭,是一种心情的状态,也是一种特殊的感受,那么有哪些成语是形容哭的'呢?下面小编就...
数字成语接龙 数字成语接龙精选  一尘不染 二龙戏珠 三生有幸 四分五裂 五光十色 六神无主 七嘴八舌 八面威风 ...
“铁钉铁铆”的意思 “铁钉铁铆”的意思 成语拼音: [tiě dīng tiě mǎo] ...
“情之所钟”的意思 “情之所钟”的意思 成语拼音: [qíng zhī suǒ zhōng] ...
“谦受益,满招损”的意思 “谦受益,满招损”的意思 成语拼音: [qiān shòu yì,mǎn zhāo sǔ...
“强唇劣嘴”的意思 “强唇劣嘴”的意思 成语拼音: [qiáng chún liè zuǐ] ...
“人云亦云”的意思 “人云亦云”的意思 成语拼音: [rén yún yì yún] ...
“变化无方”的意思 “变化无方”的意思 成语拼音: [biàn huà wú fāng] ...
“细高挑儿”的意思 “细高挑儿”的意思 成语拼音: [xì gāo tiǎo ér] ...
“分鞋破镜”的意思 “分鞋破镜”的意思 成语拼音: [fēn xié pò jìng] ...
“幺幺小丑”的意思 “幺幺小丑”的意思 成语拼音: [yāo mó xiǎo chǒu] ...
“谋臣武将”的意思 “谋臣武将”的意思 成语拼音: [móu chén wǔ jiàng] ...
“攒三集五”的意思 “攒三集五”的意思 成语拼音: [zǎn sān jí wǔ] ...
“虎视鹰瞵”的意思 “虎视鹰瞵”的意思 成语拼音: [hǔ shì yīng lín] ...
“逾淮为枳”的意思 “逾淮为枳”的意思 成语拼音: [yú huái wéi zhǐ] ...
“鸣珂锵玉”的意思 “鸣珂锵玉”的意思 成语拼音: [míng kē qiāng yù] ...
寻人启事 寻人启事范文(通用8篇)  寻人启事,汉语词语,发布寻人启事寻人,是失踪者及其亲友间相互寻找的一种基...