使用koa:

koa2是一个类,所以引入koa后,要创建实例化“对象”,才能使用koa内部封装的方法。

设置监听端口:

处理http请求:

1、http请求处理链

A、通过app.use()注册async异步函数

B、每收到一个http请求,koa就会调用通过app.use()注册的async异步函数,并传入ctxnext参数。

2、koa使用异步方法处理请求

async:异步函数

ctx:是由koa传入的封装了request和response的变量

3、next()

用await next()来调用下一个async函数

4、middleware

我们把每个async函数称为middleware

针对不同的url申请调用不同的异步函数:

底层的处理方式,是通过if判断请求的地址来进行区分的

使用if判断非常麻烦,使用koa-router省略这一个步骤

koa-router只能省略掉if判断的部分,最后要使用app.use()去调用koa-router这个异步函数

同理可以处理post请求

用post请求时,会遇到一个问题:post请求通常会发送一个表单,或者JSON,它作为request的body发送

但无论是Node.js提供的原始request对象,还是koa提供的request对象,都不提供解析request的body的功能!

引入另一个middleware ——koa-bodyparser解析request的body

var name = ctx.request.body.name || ''拿到表单的name字段,如果该字段不存在,默认值设置为''

随着需要处理的url越来越多,app.js会显得特别的臃肿

在controller文件中集中描写url:

app.js不再放置url的异步函数处理方式

app.js只用于将所有controller文件夹中的url异步函数,引入,并使用app.use为其注册

引入+注册:就两个函数封装这一些功能

进一步简化app.js

将处理引入与注册url异步函数的方法,作为一个

Controller Middleware

进一步封装到controller.js中,去处理controller文件夹中的url异步函数

  1. const fs = require('fs');
  2.  
  3. // add url-route in /controllers:
  4.  
  5. function addMapping(router, mapping) {
  6. for (var url in mapping) {
  7. if (url.startsWith('GET ')) {
  8. var path = url.substring(4);
  9. router.get(path, mapping[url]);
  10. console.log(`register URL mapping: GET ${path}`);
  11. } else if (url.startsWith('POST ')) {
  12. var path = url.substring(5);
  13. router.post(path, mapping[url]);
  14. console.log(`register URL mapping: POST ${path}`);
  15. } else if (url.startsWith('PUT ')) {
  16. var path = url.substring(4);
  17. router.put(path, mapping[url]);
  18. console.log(`register URL mapping: PUT ${path}`);
  19. } else if (url.startsWith('DELETE ')) {
  20. var path = url.substring(7);
  21. router.del(path, mapping[url]);
  22. console.log(`register URL mapping: DELETE ${path}`);
  23. } else {
  24. console.log(`invalid URL: ${url}`);
  25. }
  26. }
  27. }
  28.  
  29. function addControllers(router, dir) {
  30. fs.readdirSync(__dirname + '/' + dir).filter((f) => {
  31. return f.endsWith('.js');
  32. }).forEach((f) => {
  33. console.log(`process controller: ${f}...`);
  34. let mapping = require(__dirname + '/' + dir + '/' + f);
  35. addMapping(router, mapping);
  36. });
  37. }
  38.  
  39. module.exports = function (dir) {
  40. let
  41. controllers_dir = dir || 'controllers',
  42. router = require('koa-router')();
  43. addControllers(router, controllers_dir);
  44. return router.routes();
  45. };

这样app.js中只需要引入这个middleware,再调用就可以完成url的处理

操作数据库:

ORM技术:Object-Relational Mapping,把关系数据库的表结构映射到js对象上。

ORM框架:Sequelize

数据库配置信息,在使用Sequelize操作MySQL需要放在参数里,告诉函数应该如何做

将其保存在config.js中

  1. var config = {
  2. database: 'test', // 使用哪个数据库
  3. username: 'www', // 用户名
  4. password: 'www', // 口令
  5. host: 'localhost', // 主机名
  6. port: 3306 // 端口号,MySQL默认3306
  7. };
  8.  
  9. module.exports = config;

1、创建Sequelize对象实例

  1. //引入
    const Sequelize = require('sequelize');
  2. const config = require('./config');
  3. //对象实例化
  4. var sequelize = new Sequelize(config.database, config.username, config.password, {
  5. host: config.host,
  6. dialect: 'mysql',
  7. pool: {
  8. max: 5,
  9. min: 0,
  10. idle: 30000
  11. }
  12. });
  1. new Sequelize(database, [username=null], [password=null], [options={}])
    //option可选填

2、定义数据模型model让数据库可以创建表

  1. //第一个参数传入名称Pet,默认的表名是Pets
    //第二个参数指定列名和数据类型,如果是主键,需要更详细地指定。
    //第三个参数是额外的配置,我们传入timestamps: false是为了关闭Sequelize的自动添加timestamp的功能
  1. var Pet = sequelize.define('pet', {
  2. id: {
  3. type: Sequelize.STRING(50),
  4. primaryKey: true
  5. },
  6. name: Sequelize.STRING(100),
  7. gender: Sequelize.BOOLEAN,
  8. birth: Sequelize.STRING(10),
  9. createdAt: Sequelize.BIGINT,
  10. updatedAt: Sequelize.BIGINT,
  11. version: Sequelize.BIGINT
  12. }, {
    timestamps: false
  13. });

3、插入数据

promise方式

  1. var now = Date.now();
  2.  
  3. Pet.create({
  4. id: 'g-' + now,
  5. name: 'Gaffey',
  6. gender: false,
  7. birth: '2007-07-07',
  8. createdAt: now,
  9. updatedAt: now,
  10. version: 0
  11. }).then(function (p) {
  12. console.log('created.' + JSON.stringify(p));
  13. }).catch(function (err) {
  14. console.log('failed: ' + err);
  15. });

await方式

  1. (async () => {
  2. var dog = await Pet.create({
  3. id: 'd-' + now,
  4. name: 'Odie',
  5. gender: false,
  6. birth: '2008-08-08',
  7. createdAt: now,
  8. updatedAt: now,
  9. version: 0
  10. });
  11. console.log('created: ' + JSON.stringify(dog));
  12. })();

4、查询数据

  1. (async () => {
  2. var pets = await Pet.findAll({
  3. where: {
  4. name: 'Gaffey'
  5. }
  6. });
  7. console.log(`find ${pets.length} pets:`);
  8. for (let p of pets) {
  9. console.log(JSON.stringify(p));
  10. }
  11. })();

5、更新数据

  1. 如果要更新数据,可以对查询到的实例调用save()方法:
  2.  
  3. (async () => {
  4. var p = await queryFromSomewhere();
  5. p.gender = true;
  6. p.updatedAt = Date.now();
  7. p.version ++;
  8. await p.save();
  9. })();

6、删除数据

  1. (async () => {
  2. var p = await queryFromSomewhere();
  3. await p.destroy();
  4. })();

直接使用Sequelize虽然可以创建model,但是存在一些问题

混乱,不方便管理,不规范,无法复用

制定一个规范

A、model统一存放在models文件夹中

B、其次,每一个Model必须遵守一套规范:

  1. 统一主键,名称必须是id,类型必须是STRING(50)
  2. 主键可以自己指定,也可以由框架自动生成(如果为null或undefined);
  3. 所有字段默认为NOT NULL,除非显式指定;
  4. 统一timestamp机制,每个Model必须有createdAtupdatedAtversion,分别记录创建时间、修改时间和版本号。其中,createdAtupdatedAtBIGINT存储时间戳,最大的好处是无需处理时区,排序方便。version每次修改时自增。

这一套规范,不需要去记忆,而是通过一个db.js统一Model的定义:

  1. const Sequelize = require('sequelize');
  2.  
  3. console.log('init sequelize...');
  4.  
  5. var sequelize = new Sequelize('dbname', 'username', 'password', {
  6. host: 'localhost',
  7. dialect: 'mysql',
  8. pool: {
  9. max: 5,
  10. min: 0,
  11. idle: 10000
  12. }
  13. });
  14.  
  15. const ID_TYPE = Sequelize.STRING(50);
  16.  
  17. function defineModel(name, attributes) {
  18. var attrs = {};
  19. for (let key in attributes) {
  20. let value = attributes[key];
  21. if (typeof value === 'object' && value['type']) {
  22. value.allowNull = value.allowNull || false;
  23. attrs[key] = value;
  24. } else {
  25. attrs[key] = {
  26. type: value,
  27. allowNull: false
  28. };
  29. }
  30. }
  31. attrs.id = {
  32. type: ID_TYPE,
  33. primaryKey: true
  34. };
  35. attrs.createdAt = {
  36. type: Sequelize.BIGINT,
  37. allowNull: false
  38. };
  39. attrs.updatedAt = {
  40. type: Sequelize.BIGINT,
  41. allowNull: false
  42. };
  43. attrs.version = {
  44. type: Sequelize.BIGINT,
  45. allowNull: false
  46. };
  47. return sequelize.define(name, attrs, {
  48. tableName: name,
  49. timestamps: false,
  50. hooks: {
  51. beforeValidate: function (obj) {
  52. let now = Date.now();
  53. if (obj.isNewRecord) {
  54. if (!obj.id) {
  55. obj.id = generateId();
  56. }
  57. obj.createdAt = now;
  58. obj.updatedAt = now;
  59. obj.version = 0;
  60. } else {
  61. obj.updatedAt = Date.now();
  62. obj.version++;
  63. }
  64. }
  65. }
  66. });
  67. }

怎么调用呢db.js创建model?举个例子!

  1. //引入db.js
    const db = require('../db');
  2. //调用db.js中的defineModel,定义并暴露model
  3. module.exports = db.defineModel('users', {
  4. email: {
  5. type: db.STRING(100),
  6. unique: true
  7. },
  8. passwd: db.STRING(100),
  9. name: db.STRING(100),
  10. gender: db.BOOLEAN
  11. });

在使用model进行数据库操作时候,每一次都要导入model,如果同时使用多个model,还要写多条语句去导入,显得特别麻烦

创建一个model.js自动化导入所有的model

  1. const fs = require('fs');
  2. const db = require('./db');
  3.  
  4. let files = fs.readdirSync(__dirname + '/models');
  5.  
  6. let js_files = files.filter((f)=>{
  7. return f.endsWith('.js');
  8. }, files);
  9.  
  10. module.exports = {};
  11.  
  12. for (let f of js_files) {
  13. console.log(`import model from file ${f}...`);
  14. let name = f.substring(0, f.length - 3);
  15. module.exports[name] = require(__dirname + '/models/' + f);
  16. }
  17.  
  18. module.exports.sync = () => {
  19. db.sync();
  20. };

使用model.js

  1. //引入model.js
    const model = require('./model');
  2. //掉用导入
  3. let
  4. Pet = model.Pet,
  5. User = model.User;
  6.  
  7. var pet = await Pet.create({ ... });

使用node+mysql进行后端开发的更多相关文章

  1. 招聘前端、Java后端开发、测试、Mysql DBA

    公司介绍: http://www.lagou.com/gongsi/43095.html http://www.yamichu.com 简历发到: zhuye@yamichu.com 招聘职位: JA ...

  2. Python后端开发要求

    关于Python后端开发要求 一.对Python有兴趣,熟悉Python(标准库) 最好阅读过源码 了解Python的优化(熟悉pypy更佳) 二.至少至少一门语言(不说"精通") ...

  3. Node.js 从零开发 web server博客项目[登录]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  4. web前端开发和后端开发有什么区别?

    web前端分为网页设计师.网页美工.web前端开发工程师 首先网页设计师是对网页的架构.色彩以及网站的整体页面代码负责 网页美工只针对UI这块儿的东西,比如网站是否做的漂亮 web前端开发工程师是负责 ...

  5. 快速使用node.js进行web开发

    首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发.相信这 ...

  6. 后端开发实践——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  7. .net core webapi 前后端开发分离后的配置和部署

    背景:现在越来越多的企业都采用了在开发上前后端分离,前后端开发上的分离有很多种,那么今天,我来分享一下项目中得的前后端分离. B/S  Saas 项目:(这个项目可以理解成个人中心,当然不止这么点功能 ...

  8. 微信小程序后端开发(Java语言)笔记

    前言: 因为是第一次真正接触后端开发,从编码到部署服务器到上线,所以做个笔记,也供和我一样的开发小白一些参考. 一.前期工作:开发环境与工具: 1. 编程语言:Java    #笔者还没学PHP,只想 ...

  9. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史

    ---新内容开始--- 番外 大家周一好呀,又是元气满满的一个周一呀!感谢大家在周一这个着急改Bug的黄金时期,抽出时间来看我的博文哈哈哈,时间真快,已经到第十四篇博文了,也很顺顺(跌跌)利利 (撞撞 ...

随机推荐

  1. [POI2007]MEG-Megalopolis 树状数组 + dfs序前缀和 好题

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const ...

  2. 路飞学城Python-Day108

    96-分页器1 批量插入的方式就不能用ORM的create()方式去做了,因为create就是对sql进行insert的操作,sql最好不要每次有一条数据就去进行插入,最好的方式就是插入一组数据 fr ...

  3. 树(6)-----DFS

    1.二叉树的反向层次遍历 def levelOrderBottom1(self, root): res = [] self.dfs(root, 0, res) return res def dfs(s ...

  4. 记录python爬取猫眼票房排行榜(带stonefont字体网页),保存到text文件,csv文件和MongoDB数据库中

    猫眼票房排行榜页面显示如下: 注意右边的票房数据显示,爬下来的数据是这样显示的: 网页源代码中是这样显示的: 这是因为网页中使用了某种字体的缘故,分析源代码可知: 亲测可行: 代码中获取的是国内票房榜 ...

  5. http协议的状态码(200,404,503)

    http协议的状态码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态码. 100(继续) 请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101( ...

  6. php文件上传相关知识点回顾

    近来正在回顾PHP的文件上传.在此做个记录. <?php date_default_timezone_set('PRC'); if(isset($_POST['submit'])) { echo ...

  7. web前端对文件的引用规则

    web前端一般常用文件 .html .css .js.但是当用css文件和html引入资源(比如图片)时,路径可能不相同.下面总结了几条. 使用相对路径引入规则: html或者js引入图片,按照htm ...

  8. 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 3

    第三天 日期:2019/6/16 前言: 第3次会议在女生宿舍召开 讨论了项目功能改进问题,继续代码完善和安排 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 佳 对已 ...

  9. 关于mvc架构的浅谈

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码 ...

  10. TensorFlow 制作自己的TFRecord数据集

    官网的mnist和cifar10数据之后,笔者尝试着制作自己的数据集,并保存,读入,显示. TensorFlow可以支持cifar10的数据格式, 也提供了标准的TFRecord 格式,而关于 ten ...