云顶书院公开课-从零构建一个express+mongodb后台项目-概念准备

在讲项目之前,我们先来讲一些概念,因为大家还没有学ES6,所以这次以ES5语法来讲内容。

一、数据库MongoDB和操作数据库的工具Mongoose

在解决大家寒假项目代码问题的时候,我们发现大家有时候经常把MongoDB和Mongoose的概念搞混。MongoDB是什么?是一种基于分布式文件储存的非关系型数据库,由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。Mongoose是什么?Mongoose是在node.js异步环境下对mongodb进行便捷操作的对象模型工具。一个是数据库,一个是操作数据库的工具,二者不可混为一谈。
接下来,我简单的给大家把概念捋一下,讲完之后大家可以把我写的那两个链接好好看一下,能够帮助大家解决很多问题。

(1)、MongoDB基础

MongoDB的逻辑结构是一种层次结构,主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。

文档(document)

文档是一组键值(key-value)对(即BSON),像{a:1};{s:”abc”}等,它是MongoDB核心单元,相当于关系数据库中的一行记录。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

集合(collection)

多个文档组成一个集合(collection),相当于关系数据库的表。 集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。当你插入一个文档时,这个集合就会被创建。

数据库(database)

多个集合(collection),逻辑上组织在一起,就是数据库(database)。一个MongoDB实例支持多个数据库(database)。

学习数据库和操作之前还需要了解一些概念,Schema,Model,Entity。

Schema : 一种以文件形式存储的数据库模型骨架,每个schema会映射到mongodb中的一个collection,不具备数据库的操作能力

Model : 由Schema发布生成的模型,具有抽象属性和行为的数据库操作

Entity : 由Model创建的实体,他的操作也会影响数据库

(2)、Mongoose的使用

Mongoose官方文档
深入浅出Mongoose

安装Mongoose

npm install mongoose --save

在用Mongoose连接数据库之前要安装MongoDB数据库本身并启动

mongod --dbpath 你想保存数据的文件夹地址

使用Mongoose连接到MongoDB数据库

Mongoose会向MongoDB请求连接。你可以使用require()引入Mongoose,并使用mongoose.connect()连接到本地数据库,如下所示:


var mongoose=require("mongoose");

mongoose.connect("mongodb://localhost/test") ;// mongodb协议://主机名/数据库名,这样做的好处很明显,极大地提升了性能。

用mongoose.connection你可以获得Mongoose的默认Connection 对象。

定义Schema

Schema 用来定义存储在document 中的属性,并且赋予他们校验的规则,和默认值。另外你可以定义静态或实体的helper方法,使你的数据类型更加易于使用。你也可以定义像其他属性一样使用的虚拟属性,这些属性并不会被保存到数据库中。

下面的代码展示了如何定义一个简单的Schema。首先引入mongoose,然后使用Schema的构造方法新建一个Schema的实例,在构造函数的参数对象中定义属性。


var mongoose = require('mongoose');

var adminSchema = Schema

    ({

        //定义用户数据字段

        Nickname: {

            type: String,

            default: null

        },

        Password: {

            type: String,

            default: null

        },

        Admin_Avatar: {

            type: String,

            default: null

        },

        Created_At: {

            type: String,

            default: Date()

        },

        Updated_At: {

            type: String,

            default: Date()

        },

        State: {

            type: Number,

            default: 1

        }

    });

生成Model

Model是由Schema构造生成的模型,除了Schema定义的数据库骨架以外,还具有数据库操作的行为,类似于管理数据库属性、行为的类。使用mongoose.model()将Schema“编译”入Model。一旦拥有一个model,你可以使用他用来创建,查询,删除指定的对象。


var AdminSchema = mongoose.model('admins', adminSchema);

// 第一个参数是MongoDB中的集合的名,mongoose将为上面的Model创建一个名为 admins的集合。第二个参数是你想要用来创建Model的Schema 。

(3)、Model创建好后的使用

CURD操作其实就是指我们平时说的创建(Create)、更新(Update)、读取(Retrieve)和删除(Delete)。(增删改查)。

注意创建(以及更新,删除,查询)是异步操作,你需要传递一个回调函数,当操作完成时会执行。我们遵从错误优先的惯例,所以回调函数的第一个参数为错误信息,如果有的话。如果操作会返回结果,他将被作为第二个参数。(err,result)

查询: AdminSchema.find({ "Nickname": nickname });

增加:


// 先实例化 再进行save()

var result = new AdminSchema({ Nickname: nickname, Password: password, State: 1 });

 result.save();

修改:AdminSchema.update({ Nickname: nickname }, { Password: password, State: 1 });

删除:AdminSchema.remove({ Nickname: nickname });

方法有很多种,我只是列了其中一种帮助大家理解。

(3)、我们为什么要用Mongoose,它的优点在哪里?

  1. 可以为文档创建一个模式结构(Schema)
  2. 可以对模型中的对象/文档进行验证
  3. 数据可以通过类型转换转换为对象模型
  4. 可以使用中间件来应用业务逻辑挂钩
  5. 比Node原生的MongoDB驱动更容易

(4)、如何设计一个成熟的Schema

CSDN

说概念很难体会设计一个好的数据库结构的重要性,接下来我以简易微博网站为例设计一个简单的数据库。


项目构图

(5)、图片等大文件保存GridFS

有些同学提到了图片,视频等一些大文件内容,可不可以储存到数据库中呢?答案是可以的。

GridFS是MongoDB规范用于存储和检索大文件,如图片,音频文件,视频文件等。这是一种文件系统用来存储文件,但数据存储于MongoDB集合中。GridFS存储文件比其文档大小16MB限制的更大能力。原理就是GridFS将一个文件分成块来存储数据,每个块在一个单独的文件,每个最大尺寸255K。

这就涉及到MongoDB的一些高阶操作,目前的话,保存图片,视频等文件是将其文件上传到七牛云等,然后七牛云给我们返回图片地址,将图片地址保存到我们的数据库中。既保证了文件调用的方便性,又能保证数据库不会因为存储文件过大而导致的硬件问题。

其实我觉得,数据库是一个后台的核心,牵一发而动全身,一个优秀的数据库结构能够帮你省去很多麻烦和问题

二、JSON

目前,随着前后端分离开发,运用表单进行文件传输已不再适用,以JSON格式在前后台进行数据交互已成为常态。

(一)、什么是JSON

JSON英文全称 JavaScript Object Notation(JavaScript 对象表示法),是一种轻量级的用于存储和交换文本信息的语法,被设计用于可读的数据交换,JSON 独立于语言,类似 XML,但比 XML 更小、更快,JSON具有自我描述性,更易理解。
XML百度百科

(二)、JSON简介

JSON是从 JavaScript 脚本语言中演变而来, 使用 JavaScript 语法来描述数据对象,文件名扩展是 .json,但是JSON格式仅仅是一个文本,仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。

(三)、JSON语法

其实JSON 语法是 JavaScript 对象表示法语法的子集。
数据使用名/值对表示,名必须用双引号括住
数据由逗号分隔
花括号保存对象
方括号保存数组

JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null

以下是一个例子

{
        "name": "好一只帅卤蛋",
        "nick_name": "帅卤蛋",
        "age": 20,
        "friends": [
          { "name": "帅狗子", "age": 21, "state": true },
          { "name": "a", "age": 21, "state": true },
          { "name": "b", "age": 30, "state": false }
        ],
        "information":["avatar":"头像","sign":"签名"]
}

(四)、JSON使用Javascript语法

JavaScript对象和JSON区别:

// 对象
{
  name:"帅卤蛋",
}
// JSON
{
  "name":"帅卤蛋"
}

所以大家看出区别来了么?

区别 JSON JavaScript对象
含义 仅仅是一种数据格式 表示类的实例
传输 可以跨平台数据传输,速度快 不能传输
表现 键必须加双引号,值不能是方法函数,不能是undefined/NaN 键不加引号,值可以是函数、对象、字符串、数字、boolean 等
逗号问题 最后一个值后面不能有逗号 可以有逗号
数值问题 前导不能为0,小数点后会有值 都可以

因为 JSON 使用 JavaScript 语法,所以无需额外的软件就能处理 JavaScript 中的 JSON。JavaScript 程序使用内建的 eval() 函数,用 JSON 数据来生成原生的 JavaScript 对象。
通过 JavaScript,可以创建一个对象数组

var friends = [
          { "name": "帅狗子", "age": 21, "state": true },
          { "name": "a", "age": 21, "state": true },
          { "name": "b", "age": 30, "state": false }
        ]

然后像这样访问 JavaScript 对象数组中的第一项

friends[0].name

然后返回的内容是 帅狗子 ,也可以修改数组中的值。JSON的使用方法也如此。
JSON 最常见的用法之一,是从服务端上读取 JSON 数据(作为文件或作为 HttpRequest),将 JSON 数据转换为 JavaScript 对象,然后在客户端中使用该数据。在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象。所以,JSON对象和JSON字符串之间的相互转换是关键。

JSON.parse(jsonstr);     // 可以将json字符串转换成json对象 
JSON.stringify(jsonobj); // 可以将json对象转换成json对符串 

三、接口

这是我找的一篇介绍js接口的文章
它写的有点复杂,很难理解,简单来说,接口是一组方法签名的集合。
当请求某个接口的时候,后台可以寻找并执行对应方法,返回执行结果。
大概就像我们写的这个

// 前端携带用户名和密码用POST请求访问后台
app.post('/doLogin', router.doLogin);

如何写一篇优秀的接口文档

作者:塔克拉玛干平原
链接:https://www.zhihu.com/question/52409287/answer/130390641
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一、什么是接口文档?
在项目开发中,web项目的前后端分离开发,APP开发,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直维护。
二、为什么要写接口文档?
1、项目开发过程中前后端工程师有一个统一的文件进行沟通交流开发
2、项目维护中或者项目人员更迭,方便后期人员查看、维护
三、接口规范是什么?
首先接口分为四部分:方法、uri、请求参数、返回参数
1、方法:新增(post) 修改(put) 删除(delete) 获取(get)
2、uri:以/a开头,如果需要登录才能调用的接口(如新增、修改;前台的用户个人信息,资金信息等)后面需要加/u,即:/a/u;中间一般放表名或者能表达这个接口的单词;get方法,如果是后台通过搜索查询列表,那么以/search结尾,如果是前台的查询列表,以/list结尾;url参数就不说了。
3、请求参数和返回参数,都分为5列:字段、说明、类型、备注、是否必填字段是类的属性;说明是中文释义;类型是属性类型,只有String、Number、Object、Array四种类型;备注是一些解释,或者可以写一下例子,比如负责json结构的情况,最好写上例子,好让前端能更好理解;是否必填是字段的是否必填。
4、返回参数结构有几种情况:1、如果只返回接口调用成功还是失败(如新增、删除、修改等),则只有一个结构体:code和message两个参数;2、如果要返回某些参数,则有两个结构体:1是code/mesage/data,2是data里写返回的参数,data是object类型;3、如果要返回列表,那么有三个结构体,1是code/mesage/data,data是object,里面放置page/size/total/totalPage/list 5个参数,其中list是Arrary类型,list里放object,object里是具体的参数。
注意:uri地址里不允许出现大写字母,如果是两个单词拼接,用/分开

四、Cookie和Session

大家学完cookie和session以后,大概知道了他们是个什么意思。cookie是在客户端使用,是实际存在的东西,session是在服务端使用,是看不见摸不着的。接下来我引用一位牛人的图来说明一下
图解Cookie和Session

五、验证码发送,接口测试工具POSTMAN,代码规范问题

验证码发送
寒假有同学提到了如何发送短信验证码这个问题,其实在腾讯云,阿里云等云服务平台都可以实现。
这里是一个关于阿里云短信接口的node.js官方文档
很简单,按照提示做就可以,其中const和let是ES6的语法,定义常量和变量。但申请模板和短信签名比较困难,嗯,其实我现在也没申请到。
现阶段测试的话可以直接在后台写一个生成六位验证码的接口,当前端请求接口的时候,将验证码返回给前端去。

POSTMAN
接口测试工具有很多RAP,SoapUI,Jmeter等等,今天我给大家介绍一个叫POSTMAN的接口测试工具。postman是一个完全覆盖开发人员测试场景的接口调试工具。
大家还在用视频课里教的写一个前端Html页面,用表单提交数据?不不不,作为一名优秀的后台程序员,我们要学会用测试工具来测试我们的接口。

POSTMAN使用实例

使用postman构造这个请求的步骤如下:

选择请求方法
输入请求URL
输入请求参数值,我图上显示的是传一个JSON给后台
发送

补充一点:

 get方式,参数值放到url中,如http://192.168.0.121:3000/doRegister?a=1&b=1
 表单方式,示例中的“a=1&b=1”放在body中,头部的Content-Type是application/x-www- 
 form-urlencoded
 json传值,body是:{"a":1,"b":1},头部的Content-Type是application/json
 xml传值,头部的Content-Type是application/xml

如果大家有时间可以看一下HTTP超文本传输协议,curl命令,请求的格式,响应的格式,如何在Chrome上检查HTTP请求和响应等来帮助我们理解 请求接口等问题。

代码规范
ESlint官网文档
大家的项目代码,规范性还有待提高,大家加油!

你可能感兴趣的:(云顶书院公开课-从零构建一个express+mongodb后台项目-概念准备)