专栏首页程序员成长指北koa+react+sequelize搭建博客后台(附源码)

koa+react+sequelize搭建博客后台(附源码)

使用koa+react+sequelize搭建博客系统,这篇文章讲述koa+sequelize的开发过程。支持增删改查等功能。

代码放到了github:https://github.com/liangchaofei/cms上,可以直接下载运行

先看下系统界面

koa使用狼叔提供的koa-generate脚手架工具。

安装koa-generate

    npm install -g koa-generator

建立项目并初始化

    koa cms_blog
    cd cms_blog
    npm install

安装成功后项目目录如下:

运行并在浏览器打开127.0.0.1:3000即可

    npm run dev

开始项目搭建:采用MVC模式

  • 在根目录下创建controllers,modules,schema,config文件夹
    • controllers:写控制逻辑部分
    • modules:写sql部分
    • schema:写数据表部分
    • config:写数据库配置部分

数据库用nodejs的ORM数据库:Sequelize

  • 在config目录下创建db.js,配置数据库
    const Sequelize = require('sequelize')
    const sequelize = new Sequelize('koa','root','123456',{
        host:'localhost',
        dialect:'mysql',
        operatorsAliases:false,
        dialectOptions:{
            //字符集
            charset:'utf8mb4',
            collate:'utf8mb4_unicode_ci',
            supportBigNumbers: true,
            bigNumberStrings: true
        },
        pool:{
            max: 5,
            min: 0,
            acquire: 30000,
            idle: 10000
        },
        timezone: '+08:00'  //东八时区
    })
    
    module.exports = {
        sequelize
    }
  • 创建一个文章表article

名称

类型

长度

主键

id

int

11

true

title

varchar

255

false

authore

varchar

255

false

content

varchar

255

false

createdAt

datetime

0

false

updatedAt

datetime

0

false

  • 在schema文件夹下创建article.js
    const blog = (sequelize, DataTypes) => {
    return sequelize.define('blog',{
        id:{
            type:DataTypes.INTEGER,
            primaryKey:true,
            allowNull:true,
            autoIncrement:true
        },
        title: {
            type: DataTypes.STRING,
            allowNull: false,
            field: 'title'
        },
        author: {
            type: DataTypes.STRING,
            allowNull: false,
            field: 'author'
        },
        content: {
            type: DataTypes.STRING,
            allowNull: false,
            field: 'content'
        },
        createdAt:{
            type:DataTypes.DATE
        },
        updatedAt:{
            type:DataTypes.DATE
        }
    },{
        /**
         * 如果为true,则表示名称和model相同,即user
         * 如果为fasle,mysql创建的表名称会是复数,即users
         * 如果指定的表名称本身就是复数,则形式不变
         */
        freezeTableName: false
    })
}
module.exports =  blog

数据库部分配置好后,开始接口开发,采用restful api模式

get请求:数据查询

  • 在routes目录下创建article.js
    const router = require('koa-router')() // 使用koa-router 来指定接口路由
    const BlogControll = require('../controllers/blog') // 引入Control部分
    
    // 使用router.get 提供get请求
    router.get('/blog', BlogControll.getAllBlog)
  • 在controllers目录下创建article.js
    const BlogModel = require('../modules/blog') // 引入model
    
    static async getAllBlog(ctx) {
        const { query } = ctx.request; // 获取前端传来的参数
        try {
            let data = await BlogModel.getAllBlog(query) // 获取查询的数据
            ctx.response.status = 200;
            ctx.body = {
                code: 200,
                msg: 'success',
                data,
                count: data.length
            }
        } catch (err) {
            ctx.response.status = 412;
            ctx.body = {
                code: 412,
                msg: 'error',
                err,
            }
        }
    }
  • 在modules目录下创建article.js
    const db = require('../config/db') // 引入数据库配置
    const Sequelize = db.sequelize; // 使用sequelize
    const Blog = Sequelize.import('../schema/blog.js')
    Blog.sync({force: false})
    
    
    static async getAllBlog(query){
        // 通过使用sequelize 的findAll 来查询数据
        // 根据query参数实现查询关键词功能
        return await Blog.findAll({
            where: {
                ...query
            },
            order:[
                ["id","DESC"]
            ],
        })
      
    }
  • 至此一个get请求的接口就写好了,运行npm run dev,打开浏览器运行http://127.0.0.1:3000/api/v1/blog 就可以看到数据了。
  • 可以在后台系统中查看

post请求:数据添加

  • 在routes/article.js
    router.post('/blog', BlogControll.addBlog)
  • 在controllers/article.js
    static async addBlog(ctx) {
        let req = ctx.request.body;
        if (req.title && req.author && req.content) {
            try {
                let data = await BlogModel.addBlog(req)
                ctx.response.status = 200
                ctx.body = {
                    code: 200,
                    msg: 'success',
                    data
                }
            } catch (err) {
                ctx.response.status = 412
                ctx.body = {
                    code: 412,
                    msg: 'error',
                    err
                }
            }
        } else {
            ctx.response.status = 416
            ctx.body = {
                code: 416,
                msg: '参数不全',
            }
        }
    }
  • 在module/article.js
    static async addBlog(data){
        return await Blog.create({
            title: data.title,
            author: data.author,
            content: data.content,
        })
    }
  • 至此添加文章接口就写好了,可以在后台系统添加

delete请求:删除文章

  • 在routes/article.js
    router.delete('/blog/:id',BlogControll.deleteBlog)
  • 在controllers/article.js
    static async deleteBlog(ctx) {
        let id = ctx.params.id; // 根据id删除
        if (id) {
            try {
                let data = await BlogModel.deleteBlogs(id)
                ctx.response.status = 200;
                ctx.body = {
                    code: 200,
                    msg: 'success',
                }
            } catch (err) {
                ctx.response.status = 412;
                ctx.body = {
                    code: 412,
                    msg: 'err',
                    err
                }
            }
        } else {
            ctx.response.status = 416;
            ctx.body = {
                code: 416,
                msg: '缺少id',
            }
        }
    }
  • 在module/article.js
    static async deleteBlogs(id){
        return await Blog.destroy({
            where:{
                id
            }
        })
    }
  • 至此删除文章接口就写好了,可以在后台系统删除

put请求:编辑文章

  • 在routes/article.js
    router.put('/blog', BlogControll.updateBlog)
  • 在controllers/article.js
    static async updateBlog(ctx) {
        let req = ctx.request.body;
        try {
            let data = await BlogModel.updateBlog(req)
            ctx.response.status = 200;
            ctx.body = {
                code: 200,
                msg: 'success',
            }
        } catch (err) {
            ctx.response.status = 412;
            ctx.body = {
                code: 412,
                msg: 'error',
                err
            }
        }
    }
  • 在module/article.js
    static async updateBlog(data){
        const {id,title,author,content} = data;
        console.log('id',id)
        return await Blog.update(
            {
                title,
                author,
                content,
                id
            },
            {
                where:{
                    id
                }
            }
        )
    }
  • 至此更新文章接口就写好了,可以在后台系统更新

总结:以上通过koa+sequelize实现了增删改查的接口。代码放到了github:https://github.com/liangchaofei/cms上,可以直接下载运行。如果这篇文章对您有帮助,感谢star

本文分享自微信公众号 - 程序员成长指北(coder_growth),作者:curry

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Console 模块解读及简单实现

    Console 模块提供了简单的调试功能,这在一些测试调试中有时也是使用最方便、用的最多的,它和浏览器中的 console 类似,但是在浏览器中它是同步的,在 ...

    coder_koala
  • 译 | 如何为开源代码库作出贡献——进阶途径

    如果你和我一样,希望为开源软件做出贡献,又不敢将第一个 pull request 发送至其他团队的代码仓库。

    coder_koala
  • jwt 实践应用以及特殊案例思考

    JSON Web Token 是 rfc7519[1] 出的一份标准,使用 JSON 来传递数据,用于判定用户是否登录状态。

    coder_koala
  • mybatis文件映射之利用collection定义关联集合(五)

    说明:这实际上是多对一查询,即一个部门里面有多个员工。collection标签中property属性标识Department类中的成员属性,ofType标识其类...

    绝命生
  • SpringBoot整合elasticsearch

    dalaoyang
  • Jupyterlab 使用手册:号称要取代 Jupyter Notebook

    数据显示,Github上有超过300万个 Jupyter Notebook 可供公开使用。私有的 Notebook 数量也大致相同。即使没有这些数据佐证,我们也...

    Python猫
  • 自动驾驶「无视」障碍物:百度研究人员攻陷激光雷达

    用激光雷达进行目标检测是目前汽车用到的主流方法,这种传感器精度高、成本高昂、技术门槛高。如果昂贵的价格能买来安全,那么也能显示其价值。但最近,来自百度研究院、密...

    小小詹同学
  • 自动驾驶「无视」障碍物:百度研究人员攻陷激光雷达

    用激光雷达进行目标检测是目前自动驾驶汽车用到的主流方法,这种传感器精度高、成本高昂、技术门槛高。如果昂贵的价格能买来安全,那么也能显示其价值。但最近,来自百度研...

    机器之心
  • 停启服务打包解压的脚本

    小小明童鞋
  • bert之token embeddings、segmentation embeddings、position embeddings

    token embeddings、segmentation embeddings、position embeddings。

    绝命生

扫码关注云+社区

领取腾讯云代金券