用koa的脚手架koa-generator可以快速生成项目骨架,可以用于发开或者测试接口
https://github.com/hellojinjin123/node-koa2-template

1. 全局安装koa-generator(不用全局安装koa)

项目名字fast-koa

 npm install koa-generator -gkoa2 fast-koacd fast-koanpm install

目录结构如下
-bin // www 项目启动目录 node ./www
-public // 静态网站放置目录 也就是vue dist代码放置的地 项目入口index.html
-routes // 路由
-views // 视图 服务器渲染使用的模板
-app.js // 项目入口
-packaga.json

2. 启动项目

 // package.json "scripts": {    "start": "node bin/www",    "dev": "./node_modules/.bin/nodemon bin/www",    "prd": "pm2 start bin/www",    "test": "echo "Error: no test specified" && exit 1"  }

运行npm run dev开启服务器
同时可以看到generator自带了nodemon(Nodemon 是一款非常实用的工具,用来监控你 node.js 源代码的任何变化和自动重启你的服务器)
如下图:服务器启动了

3. 项目入口app.js

 // app.jsconst Koa = require('koa')const app = new Koa()const views = require('koa-views')const json = require('koa-json')const onerror = require('koa-onerror')const bodyparser = require('koa-bodyparser')const logger = require('koa-logger')const index = require('./routes/index')const users = require('./routes/users')// error handleronerror(app)// middlewaresapp.use(bodyparser({  enableTypes:['json', 'form', 'text']}))app.use(json())app.use(logger())app.use(require('koa-static')(path.resolve(__dirname, config.publicPath))))app.use(views(__dirname + '/views', {  extension: 'pug'}))// loggerapp.use(async (ctx, next) => {  const start = new Date()  await next()  const ms = new Date() - start  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)})// routesapp.use(index.routes(), index.allowedMethods())app.use(users.routes(), users.allowedMethods())// error-handlingapp.on('error', (err, ctx) => {  console.error('server error', err, ctx)});module.exports = app

可以在根目录路添加config.js 把一些公共的配置放入 比如数据库信息,端口,静态资源路径等

 // config.jsconst path = require('path');const config = {    // 项目启动监听的端口    port: 3000,    publicPath: 'public',    logPath: 'logs/koa-template.log',    // 数据库配置    database: {        HOST: 'xxx',    // 数据库地址        USERNAME: 'xxx',    // 用户名        PASSWORD: 'xxx',    // 用户密码        DATABASE: 'xxx',    // 数据库名        PORT: 3306      // 数据库端口(默认: 3306)    }};module.exports = config;

4. koa-static 静态资源中间件

app.use(require('koa-static')(path.resolve(__dirname, config.publicPath))))
koa-generator已经配置了静态资源中间件,只要放入public目录,静态网站就可以运行
浏览http://localhost:3000/,服务器会优先读取public下的index.html
如果没有index.html,服务器会根据路由,判断'/'是否有内容返回,没有对应路由则返回404 not found
因为koa-generator默认设置了路由,所以服务器运行返回了Hello Koa 2!
如下:

 router.get('/', async (ctx, next) => {  await ctx.render('index', {    title: 'Hello Koa 2!'  })})

5. 添加models目录

相当于服务器数据层,存放数据库模型(相当于建表),使用Sequelize进行mysql操作

 const { sequelize, Sequelize } = require('../config/db')const { DataTypes, Model } = Sequelizeclass Admin extends Model {    /**     * @description: 添加管理员     * @param {*} username     * @param {*} password     * @return {*} 返回添加的数据     */    static async createAdmin({ username, password }) {        return await this.create({            username,            password        })    }    /**     * @description: 根据id修改管理员密码     * @param {*} id     * @return {*}  返回修改的数据     */        static async updatepwdById({id, password}) {        return await this.update({ password }, {            where: {                id            }        })    }    /**     * @description: 根据id删除管理员     * @param {*} id     * @return {*}      */        static async deleteById(id){        return await this.destroy({            where: {                id            }        })    }}// 初始化表结构Admin.init(    {        id: {            type: DataTypes.INTEGER,            allowNull: false, //非空            autoIncrement: true, //自动递增            primaryKey: true //主键        },        username: {            type: DataTypes.STRING,            field: "username",            allowNull: false,            unique: true   // 唯一约束 用户名不能重复        },        password: {            type: DataTypes.STRING,            allowNull: false        },        active: {            type: DataTypes.BOOLEAN,            allowNull: false,            defaultValue: true        }    }, {    underscored: true, //额外字段以下划线来分割    timestamps: true, //取消默认生成的createdAt、updatedAt字段    createdAt: "created_at",    updatedAt: "updated_at",    freezeTableName: true, // Model 对应的表名将与model名相同    comment: "管理员表类",    // paranoid: true      //虚拟删除    sequelize, // 我们需要传递连接实例    // modelName: 'Admin', // 我们需要选择模型名称    // tableName: 'Admin'  // 表名})    // 创建表格    ; (async () => {        await Admin.sync();        console.log("Admin表刚刚(重新)创建!");        // 这里是代码    })()// 定义的模型是类本身// console.log(User === sequelize.models.User); // truemodule.exports = Admin

6. mysql数据库的使用(Sequelize stars 23.6k in github )

Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server. 它具有强大的事务支持, 关联关系, 预读和延迟加载,读取复制等功能。

Sequelize 遵从 语义版本控制。 支持 Node v10 及更高版本以便使用 ES6 功能。https://www.sequelize.com.cn/core-concepts/model-basics

安装mysql&sequelize

 npm install --save mysql mysql2npm install --save sequelize

安装sequelize之后,在config目录下创建db.js,进行数据库连接设置

 const Sequelize = require('sequelize');const db = require('./index').db// 初始化数据库const sequelize = new Sequelize(db.database, db.username, db.password, {    host: db.host,    dialect: 'mysql',    pool: {        max: 5,        min: 0,        idle: 10000    }})//测试数据库链接sequelize.authenticate().then(function() {    console.log("数据库连接成功");}).catch(function(err) {    //数据库连接失败时打印输出    console.error(err);    throw err;});             module.exports = { sequelize, Sequelize }

7. 添加controllers目录

有了模型层对操作数据库的支持,就可以进行业务操作了,也就是控制器目录(在这个层可以放心调用models层方法进行curd)

 // 导入模型const Admin = require('../models/admin')module.exports = {    async getAllAdmins(ctx, next) {        try {            let data = await Admin.findAll()            ctx.body = { msg: 1001, data }        } catch (err) {            ctx.body = { code: -1, msg: 1000, }        }        await next();    },    async createAdmin(ctx, next) {        let req = ctx.request.body        if (!req.username || !req.password) {            ctx.body = { code: -1, msg: 1002 }            return await next();        }        try {            let data = await Admin.createAdmin(req)            ctx.body = { msg: 1003, data }        } catch (err) {            ctx.body = { code: -1, msg: 1000 }        }        await next();    },    async updatepwdById(ctx, next) {        let req = ctx.request.body        if (req.id && req.password) {            try {                await Admin.updatepwdById(req)                ctx.body = { msg: 1004 }            } catch (err) {                ctx.body = { code: -1, msg: 1000 }            }        } else {            ctx.body = { code: -1, msg: 1002 }        }        await next();    },    async deleteById(ctx, next) {        let query = ctx.request.query // 获取get请求参数        if (query && query.id) {            try {                await Admin.deleteById(query.id)                ctx.body = { msg: 1005 }            } catch (err) {                ctx.body = { code: -1, msg: 1000 }            }        } else {            ctx.body = { code: -1, msg: 1002 }        }        await next();    }}

8. 路由配置

 // app.js 中添加// routesconst admin = require('./routes/admin')app.use(admin.routes(), admin.allowedMethods())

到此为止,一个完整的请求(接口)就处理完成了
比如请求 http://localhost:3000/admin/getAllAdmins

koa经历的简单过程:

  1. 浏览器发出请求 -> 中间件 ->路由中间件 -> 中间件 -> 中间件若干回调 -> 浏览器收到响应
  2. 路由:
  • router.get/post -> controllers.func -> models.func-> mysql
  • 请求行为 -> 业务逻辑 -> 模型支持 -> 入库

9. 配置自定义的中间件处理日志和response消息

可以参考github代码

10. 附上一个很好理解的中间件原理的简析

 // 根目录下test.js// koa2 中间件原理简析// 中间件的仓库const arr = [    async (next) => {        console.log(1);        await next();        console.log(2);    },    async (next) => {        console.log(3);        await new Promise((resolve, reject) => {            setTimeout(() => {                resolve(                    console.log(4)                );            }, 3000);        }); // 异步操作 await 会等待后面的promise resolve 后再向下执行        await next();        console.log(5);    },    async (next) => {        console.log(6);    },    async (next) => {        // 不会执行 因为上一个函数中没有执行next        console.log(7);        await next();        console.log(8);    },    async (next) => {        // 不会执行 因为前面的函数中没有执行next        console.log(9);    }];function fun(arr) {    function dispose(index) {        const currentFun = arr[index];        const next = dispose.bind(null, index + 1);        return currentFun(next); // 尾递归    }    dispose(0);}

mysql建表的auto_increment_koa2+koa+mysql快速搭建nodejs服务器相关推荐

  1. mysql建表测试_总结MySQL建表、查询优化实用小技巧

    MySQL建表阶段是非常重要的一个环节,表结构的好坏.优劣直接影响着后续的管理维护,赶在明天上班前分享总结个人MySQL建表.MySQL查询优化积累的一些实用小技巧. 技巧一.数据表冗余记录添加时间与 ...

  2. linux mysql 建表 ddl,linux安装mysql和mysqlDDL语言

    原标题:linux安装mysql和mysqlDDL语言 声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权:凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记. li ...

  3. navicat mysql 建表语句_Navicat for MySQL怎么/如何创建数据表?Navicat for MySQL创建数据表教程_斗蟹游戏网...

    [斗蟹攻略]Navicat for MySQL是针对MySQL数据库管理而研发的管理工具,创建数据表是其最基本操作,下面就由斗蟹小编介绍Navicat for MySQL创建数据表的方法. Navic ...

  4. mysql 建表 日期格式_MySQL建表时,日期时间类型选择

    MySQL(5.5)所支持的日期时间类型有:DATETIME. TIMESTAMP.DATE.TIME.YEAR. 几种类型比较如下: 日期时间类型 占用空间 日期格式 最小值 最大值 零值表示 DA ...

  5. mysql建表2个索引是啥意思_Mysql建表与索引使用规范详解

    本篇文章是对Mysql建表和索引使用规范进行了详细的分析介绍,需要的朋友参考下 一. MySQL建表,字段需设置为非空,需设置字段默认值. 二. MySQL建表,字段需NULL时,需设置字段默认值,默 ...

  6. mysql 建表时建立索引_mysql 分享建表和索引的几点规范

    一. MySQL建表,字段需设置为非空,需设置字段默认值. 二. MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL. 三. MySQL建表,如果字段等价于外键,应在该字段加索引. ...

  7. 基于表的数据字典构造MySQL建表语句

    表的数据字典格式如下: 如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确. 写了个Perl脚本,可快速构造MySQL脚本语句. 脚本如下: #!/usr/bin/perl use str ...

  8. mysql建表是要注意什么问题_MySQL建表注意事项

    1.建表规范 -- 数据库名丶表名,全部使用小写字母,使用"_"下划线连接且长度小于12,做到见名知意 2.建议使用 innodb 引擎,这也是MySQL的默认引擎 3.字段类型选 ...

  9. Python3 使用 pymysql 连接 MySQL 建表时出现 Warning3719 UTF8 警告

    在学习 Python3 爬虫关系型数据库储存时,利用 pymysql 连接 MySQL 建表,测试用的代码如下,第一句 SQL 用于获取当前 MySQL 的版本信息,第二句 SQL 执行创建 spid ...

最新文章

  1. matplotlib各个部分
  2. [转载]能改变你的世界观的组图——从十亿光年到一飞米
  3. 取两个日期相差几年_干货~44个最常用的日期和时间类函数组合
  4. php创建分页类,一个最强的PHP通用分页类
  5. LeetCode 2007. 从双倍数组中还原原数组(map)
  6. 3星|《财经》2017年第29期:未来,国有资本的收益和变现都是补贴社保的渠道...
  7. 【报告分享】2021企业营销数字化转型研究报告.pdf(附下载链接)
  8. Linux SSH免密码登录与拷贝文件(SCP)- 亲测
  9. 不同设备监控图像传输方式分析
  10. Hive窗口函数应用:级联累加求和场景
  11. 判断运行环境是手机还是 PC
  12. Nginx--网页压缩与图片压缩
  13. 有线网与无线网(WIFI)网速的限制因素与Wifi信道选择
  14. php中rand函数怎么用,php rand函数用法是什么
  15. vba-msgbox用法详解
  16. Javaweb中上传图片,获取路径
  17. 聚会通知html文件,同学聚会通知范文 聚会邀请词精美语句
  18. java计算机毕业设计校园订餐系统源代码+数据库+系统+lw文档
  19. JAVA企业面试题精选 数据库31-40
  20. 深入CSS vertical-align属性

热门文章

  1. python爬虫编程100例_哪种Python程序员最赚钱?爬虫数据告诉你!
  2. Python入门100题 | 第009题
  3. JAVA API实现HDFS操作(二)操作函数
  4. Cmd Markdown 公式指导手册
  5. [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform
  6. gradlew wrapper使用下载到本地的gradle.zip文件装配--转
  7. Apache Hadoop YARN – NodeManager--转载
  8. Where Should an Architect Begin?--reference
  9. 李宏毅深度学习——深度学习介绍
  10. 数学建模学习笔记——插值算法