zoukankan      html  css  js  c++  java
  • 分享 koa + mysql 的开发流程,构建 node server端,一次搭建个人博客

    前言

    由于一直在用 vue 写业务,为了熟悉下 react 开发模式,所以选择了 react。数据库一开始用的是 mongodb,后来换成 mysql 了,一套下来感觉 mysql 也挺好上手的。react-router、koa、mysql 都是从0开始接触开发的,期间遇到过很多问题,印象最深的是 react-router 参考官方文档配置的,楞是跑不起来,花费了好几个小时,最后才发现看的文档是v1.0, 而项目中是v4.3, 好在可参考的资料比较多,问题都迎刃而解了。

    博客介绍

    • 前端项目通过 create-react-app 构建,server端通过 koa-generator 构建
    • 前后端分离,博客页、后台管理都在 blog-admin 里,对含有 /admin 的路由进行登录拦截
    • 前端: react + antd + react-router4 + axios
    • server端: koa2 + mysql + sequelize
    • 部署:server端 运行在 3000 端口,前端 80 端口,nginx设置代理

    预览地址

    web端源码

    server端源码

    喜欢或对你有帮助,欢迎 star

    功能

    • [x] 登录
    • [x] 分页
    • [x] 查询
    • [x] 标签列表
    • [x] 分类列表
    • [x] 收藏列表
    • [x] 文章列表
    • [x] 发布文章时间轴
    • [x] 文章访问次数统计
    • [x] 回到顶部
    • [x] 博客适配移动端
    • [ ] 后台适配移动端
    • [ ] 对文章访问次数进行可视化
    • [ ] 留言评论
    • [ ] 渲染优化、打包优化

    效果

    标签

    分类

    收藏

    文章

    编辑

    博客页

    响应式


    运行项目

    前端

    git clone https://github.com/gzwgq222/blog-admin.git
    cd blog-admin
    npm install
    

    localhost:2019

    server 端

    本地安装 mysql,新建 dev 数据库

    git clone https://github.com/gzwgq222/blog-server.git
    cd blog-server
    npm install
    

    server 端

    前端 react + antd 开发,较为平缓,在此就不再叙述。主要记录下 koa + mysql 相关事宜

    全局安装 koa-generator

    npm install -g koa-generato
    

    创建 node-server 项目

    koa node-server 
    

    安装依赖

    cd node-server 
    npn install
    

    运行

    npm dev
    

    出现 Hello Koa 2! 表示运行成功

    先看routes文件

    index.js

    const router = require('koa-router')()
    router.get('/', async (ctx, next) => {
      await ctx.render('index', {
        title: 'Hello Koa 2!'
      })
    })
    router.get('/string', async (ctx, next) => {
      ctx.body = 'koa2 string'
    })
    router.get('/json', async (ctx, next) => {
      ctx.body = {
        title: 'koa2 json'
      }
    })
    module.exports = router
    

    users.js

    const router = require('koa-router')()
    router.prefix('/users')
    router.get('/', function (ctx, next) {
      ctx.body = 'this is a users response!'
    })
    router.get('/bar', function (ctx, next) {
      ctx.body = 'this is a users/bar response'
    })
    module.exports = router
    

    分别访问下列路由

    localhost:3000/string
    localhost:3000/users
    localhost:3000/bar

    大概你已经猜到了,koa-router 定义路由访问时返回相应的内容,那我们只需要把相应的 data 返回去就行了,只是我们的数据得从数据库查询出来。

    本地安装 mysql

    项目安裝 mysql

    npm install mysql --save
    

    项目安裝 sequelize

    sequelize 是 ORM node框架,对SQL查询语句的封装,让我们可以用OOP的方式操作数据库

    npm install --save sequelize
    

    新建 sequelize.js,建立连接池

    const Sequelize = require('sequelize');
    const sequelize = new Sequelize('dev', 'root', '123456', {
      host: 'localhost',
      dialect: 'mysql',
      operatorsAliases: false,
      pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000
      }
    })
    sequelize
      .authenticate()
      .then(() => {
        console.log('MYSQL 连接成功......');
      })
      .catch(err => {
        console.error('链接失败:', err);
      });
    // 根据模型自动创建表
    sequelize.sync()
    module.exports = sequelize
    

    创建 model、controllers 文件夹 定义model:定义表结构;controller:定义对数据库的查询方法

    以 tag.js 为例

    model => tag.js

    const sequelize = require('../sequelize ')
    const Sequelize = require('sequelize')
    const moment = require('moment') // 日期处理库
    // 定义表结构
    const tag = sequelize.define('tag', { 
      id: {
        type: Sequelize.INTEGER(11), // 设置字段类型
        primaryKey: true, // 设置为主建
        autoIncrement: true // 自增
      },
      name: {
        type: Sequelize.STRING,
        unique: { // 唯一
          msg: '已添加'
        }
      },
      createdAt: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.NOW,
        get() {
          // this.getDataValue 获取当前字段value
          return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm')
        }
      },
      updatedAt: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.NOW,
        get() {
          return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm')
        }
      }
    },
    {
      // sequelize会自动使用传入的模型名(define的第一个参数)的复数做为表名 设置true取消默认设置
      freezeTableName: true
    })
    module.exports = tag
    

    controller => tag.s 定义了 create、findAll、findAndCountAll、destroy 方法

    const Tag = require('../model/tag')
    const Op = require('sequelize').Op
    const listAll = async (ctx) => {
      const data = await Tag.findAll()
      ctx.body = {
        code: 1000,
        data
      }
    }
    const list = async (ctx) => {
      const query = ctx.query
      const where = {
        name: {
          [Op.like]: `%${query.name}%`
        }
      }
      const {rows:data, count: total } = await Tag.findAndCountAll({
        where,
        offset: (+query.pageNo - 1) * +query.pageSize,
        limit: +query.pageSize,
        order: [
          ['createdAt', 'DESC']
        ]
      })
      ctx.body = {
        data,
        total,
        code: 1000,
        desc: 'success'
      }
    }
    const create = async (ctx) => {
      const params = ctx.request.body
      if (!params.name) {
        ctx.body = {
          code: 1003,
          desc: '标签不能为空'
        }
        return false
      }
      try {
        await Tag.create(params)
        ctx.body = {
          code: 1000,
          data: '创建成功'
        }
      }
      catch(err) {
        const msg = err.errors[0]
        ctx.body = {
          code: 300,
          data: msg.value + msg.message
        }
      }
    }
    const destroy = async ctx => {
      await Tag.destroy({where: ctx.request.body})
      ctx.body = {
        code: 1000,
        desc: '删除成功'
      }
    }
    module.exports = {
      list,
      create,
      listAll,
      destroy
    
    

    在 routers 文件夹 index.js 中引入定义好的 tag controller ,定义路由

    const router = require('koa-router')()
    const Tag = require('../controllers/tag')
    // tag
    router.get('/tag/list', Tag.list)
    router.get('/tag/list/all', Tag.listAll)
    router.post('/tag/create', Tag.create)
    router.post('/tag/destroy', Tag.destroy)
    module.exports = router
    /* 如每个 route 是单独的文件,可以使用 router.prefix 定义路由前缀
    router.prefix('/tag')
    router.get('/list', Tag.list)
    router.get('/list/all', Tag.listAll)
    router.post('/create', Tag.create)
    router.post('/destroy', Tag.destroy)
    */
    

    因为 app 中 已经引入 routers 中的 index.js 调用了 app.use了,所以此处不需再引入
    在浏览器里输入 localhost:3000/tag/list 就可以看到返回的数据结构了,只不过 data 为空数组,因为我们还没添加进去任何数据
    到这里,model 定义表结构、sequelize操作数据库、koa-router 定义路由 这一套流程算是完成了,其他表结构,接口 都是一样定义的

    总结

    之前没有写过 node server 和 react,算是从零搭建该博客,踩了一些坑,也学到了很多东西,譬如react 开发模式、react-router、sequelize 操作mysql的crud、koa、nginx的配置等等。

    麻雀虽小,也是一次完整的前后端开发体验,脱离了浏览器的限制,像海贼王一样,打开了新世界的大门,寻找 onepiece ......

    web端源码

    server端源码

    详细的 server 端说明

    后续会在个人博客中添加关于此次部署文章

    初尝 react + Node,错误之处还望斧正,欢迎提 issue

  • 相关阅读:
    平方十位数
    随意组合
    显示二叉树
    四阶幻方
    方格填数
    数字排列
    青蛙跳N阶(变态跳)
    Mysql可重复读、避免幻读原理
    动态规划典型例题--连续子数组的最大和
    行列有序的二维数组查找
  • 原文地址:https://www.cnblogs.com/hi-shepherd/p/10635353.html
Copyright © 2011-2022 走看看