使用Node.js+Koa 从零开始写个人博客系统系列
提示:在此文章中你可以学习到的内容如下:
1 如何使用Koa快速搭建项目
2 对Koa的核心组件Koa-Route的简单使用
3 3层架构思想
4 nodejs的ORM框架——sequelize的使用
5 sequelize-auto的使用
6 简单的增删查改
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 使用Node.js+Koa 从零开始写个人博客系统系列
- 前言
- 开始吧
- 1.0 关于node.js
- 什么是Node.js?
- 优缺点如何?
- 适用场景如何?
- 1.1 创建Node.js项目
- 新建nodejs项目
- 1.2 初步填充app.js文件
- 什么是Koa?
- 什么是Koa-router?
- 在app.js中替换为以下代码
- 1.3 创建router中的文件
- 1.4 创建新的index.js
- 1.5 新建控制器js文件
- 1.6 替换路由文件
- 2.1 使用sequelize
- 简单使用
- 2.2 执行sql语句
- 2.3使用sequelize-automate
- 2.5 更改config/dbconfig.js
- 2.6 测试sequelize是否可以连接数据库
- 2.7 使用增删改查
- 2.8 抽离数据库连接代码至Core中
前言
此项目始终贯彻在做实际项目中,学习新的知识,适合看不进去视频,或者官方文档的人阅读,
小白也能上手操作,大佬也能理清思路,话不多说上车!!
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
开始吧
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')
return
const 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 # 这将安装最新版本的 Sequelize
npm 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');
});