node.js 从基础到操作数据库
node.js 学习
模块化
- CommonJS----------双端(1.浏览器端;2.服务器端)------暴露:module.exports =??? exports.xxxx = ??? 浏览器不认识require ---------Browserify
- AMD--------- 只有浏览器端 ----------RequireJS-----define([‘ass’,‘dsfd’],function(){return ???})
- CMD------sea.js----借鉴,------国产的
- ESE6------前端人员主要使用的--------babel----------Browserify
Node.js是什么?
Node.js有什么特点
优点
- 异步非阻塞的I/O(I/O线程池)
2)特别适合于I/O密集型应用(对比传统java服务器)
3)事件循环机制(独有的一套,与浏览器不一样)
4)单线程(成也单线程,败也单线程)
5)跨平台(Chrome)
arguments
这是参数获取
callee 输出谁调用的
function (exports, require, module, __filename, __dirname) {console.log(arguments.callee.toString());
}// exports : 用于支持CommonJS模块化规范的暴露语法
// require : 用于支持CommonJS模块化规范的引用语法
// module : 用于支持CommonJS模块化规范的暴露语法
// __filename : 当前文件运行的路径,绝对的
// __dirname : 当前运行文件所在文件夹的绝对路径// 2. 为什么要设计这个外层函数?
// 1). 用于支持模块化语法
// 2). 隐藏服务器内部实现(从作用域)
Node中的global
// 2. Node端,js有几部分组成?
/*** 1. 没有了BOM------> 因为服务器不需要(服务端没有浏览器对象)* 2. 没有了DOM ------> 因为没有浏览器窗口* 3. 几乎包含了所有的ES规范* 4. 没有了window,但是取而代之的是一个叫做global的全局变量*/// 3.global的一些常用属性/*
clearInterval: 清除循环定时器
clearTimeout: 清除延时定时器
setInterval: 设置循环定时器
setTimeout: 设置延时定时器
clearImmediate: 清除立即执行函数
setImmediate: 设置立即执行函数
*/// 禁止Node中的this指向global
Node.js 事件循环,定时器和 process.nextTick()
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │└───────────────────────────┘
/*
clearInterval: 清除循环定时器
clearTimeout: 清除延时定时器
setInterval: 设置循环定时器
setTimeout: 设置延时定时器
clearImmediate: 清除立即执行函数
setImmediate: 设置立即执行函数*/
/*** @author: 付立翔* @method: 这个是一个事件循环* @param {*}* @Date: 2021-06-19 12:00:01* @return {*}*/
/* 第一个阶段:timers (定时器阶段) -------------------------------------------------------------------------------------------------| 1. 开始计时 \2. 执行定时器的回调 \第二个阶段:pending callbacks (系统阶段) ---\ \这个阶段不用太过关注,基本用不到 \第三个阶段:idle,prepare (准备阶段) ---------/ \|---------|第四个阶段:poll (轮询阶段,核心) | 一直循环 |----如果回调队列里有待执行的回调函数 |---------|从回调队列中取出回调函数,同步执行(一个一个执行) |----如果回调队列为空 |----如果有设置过setImmediate |进入下一个check阶段:为了执行setImmediate所设置的回调 |----如果未设置过setImmediate |再次阶段停留,等待回调函数被插入回调队列 |若定时器到点了,进入下一个check阶段,原因: 为了走第五阶段,随后走第六阶段,随后第一阶段(最终目的) |第五个阶段:check (专门用于执行setImmediate所设置的回调) ||第六个阶段:close callbacks (关闭回调阶段) ||process.nextTick()----> 用于设置立即执行函数("VIP"----能在任意阶段优先执行)------------------------------------------------------------------- |
*/// 延时定时器--------------------------------------------------- 得出结论
setTimeout(() => {console.log("我是setTimeout(延时定时器)"); /** 可能延时定时器会在第一阶段执行,也有可能循环一圈在执行 */
});// 立即执行函数(回调)
setImmediate(() => {console.log("我是setImmediate(立即执行函数)");
})// 立即执行函数(回调) 权重最够,不过在那个阶段都优先执行
// process.nextTick(()=>{// console.log("我是process.nextTick(立即执行函数)");
// })/* 一旦主线程那么就延时定时器先执行 */
// 主线程----------------------------------------------------- 得出结论 因为主线程上有代码,运行需要时间,所以就会给setTimeout 定时器留出时间来进行判断和执行
console.log("我是主线程上的代码");
Buffer缓冲器
Buffer是什么?
Buffer是一个和数组相似的对象,不同是Buffer是专门用来保存二进制数据的.
它是一个[类似于数据]的m对象,用于存储数据(存储的是二进制数据).
Buffer的效率很高,存储和读取很快,它是直接对计算机的内存进行操作.
Buffer的大小一旦去定了,不可修改
每个元素占用内存的大小为1字节
Buffer是Node中的非常核心的模块,无需下载,无需引入,直接使用即可
// 类 构造函数 // 创建一个Buffer的实例------性能特别差,会清理 // let buf = Buffer(10); // console.log(buf);// 创建一个Buffer的实例------性能比New Buffer强一点,找没有人用过的 // let buf2 = Buffer.alloc(10); // console.log(buf2);// 创建一个Buffer的实例------性能最好的,但是不安全,不会清理,不会去找没有人用过的 /*** 1. 输出的Buffer里有大于1的?* 2. 输出的Buffer 不为空?*/ // let buf3 = Buffer.allocUnsafe(10); // console.log(buf3);// 将数据存入一个Buffer实例 let buf4 = Buffer.from('hello atguigu'); console.log(buf4.toString()); /*** 1. 输出为什么不是我们曾经存入的字符串?用户存储的不一定是字符串,可能是媒体类型的文件* * 2. 如何能够让输出的东西是字符串(我们能看懂的)?toString();*/
文件写入
简单的文件写入
流式文件写入
// 只要用到了流就必须监视流的状态
let ws = createWriteStream(__dirname + '/demo.txt');
ws.on('open', function () {console.log('流打开了');
});ws.write('傻逼\t');ws.close(); // 使用方法关闭数据丢失
ws.end();
ws.on('close', function () {console.log('流关闭了');
})
流文件读取
–options:
–flags
–encoding
–fd
–mode
–autoCLose
–emitCLose
–start : 起始
–end : 结束偏移量
–highWaterMark: 每次读取数据的大小 1024
数据库操作
关系型数据库
mysql.Oracle.DB2.SQL Server
优点:
易于维护,
使用方便
高级查询
缺点:
读写性能比较差,尤其是海量数据的高效率读写;
有固定的表结构,字段不可随意更改,灵活度稍欠
高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈
非关系型数据库
mogodb,Redis
特点:关系不紧密,有文档,有键值对
Redis特点:高速缓存
优点
格式灵活
速度快:使用内存做为载体
易用
安装mongodb
下载完配置环境变量,
在c盘新建data/db文件夹
新建data/log
mongod.cfg
systemLog:destination: filepath: c:\data\log\mongod.log
storage:dbPath: c:\data\db
net:port: 27017
cmd
sc.exe create MongoDB binPath= "\"E:\MongoDB\bin\mongod.exe\" --service --config=\"E:\MongoDB\mongod.cfg\"" DisplayName= "MongoDB" start= "auto"
sc delete 服务名
MongoDB 基本命令
MongoDB原生CRUD(增删改查)命令总结
-C creat:
db.集合名.insert(文档对象)
db.集合名.insertOne(文档对象)
db.集合名.insertMany([文档对象,文档对象])
-R read:
db.集合名.find(查询条件[,投影])举例:db.students.find({age:18}),查找年龄为18的所有信息举例:db.students.find({age:18,name:'jack'}),查找年龄为18且名字为jack的学生常用操作符:1. < , <= , > , >= , !== 对应为: $lt $lte $gt $gte $ne举例:db.集合名.find({age:{$gte:20}}),年龄是大于等于20的2.逻辑或:使用$in 或 $or查找年龄为18或20的学生举例:db.students.find({age:{$in:[18,20]}})举例:db.students.find({$or:[{age:18},{age:20}]})3.逻辑非:$nin4.正则匹配:举例:db.students.find({name:/^T/})5.$where能写函数:db.students.find({$where:function(){return this.name === 'zhangsan' && this.age === 18}})投影:过滤掉不想要的数据,只保留想要展示的数据举例:db.students.find({},{_id:0,name:0}),过滤掉id和name举例:db.students.find({},{age:1}),只保留age补充:db.集合名.findOne(查询条件[,投影]),默认只要找到一个
-U update:
db.集合名.update(查询条件,要更新的内容[,配置对象])//如下会将更新内容替换掉整个文档对象,但_id不受影响举例:db.students.update({name:'zhangsan'},{age:19})//使用$set修改指定内容,其他数据不变,不过只能匹配一个zhangsan举例:db.students.update({name:'zhangsan'},{$set:{age:19}})//修改多个文档对象,匹配多个zhangsan,把所有zhangsan的年龄都替换为19举例:db.students.update({name:'zhangsan'},{$set:{age:19}},{multi:true})补充:db.集合名.updateOne(查询条件,要更新的内容[,配置对象])db.集合名.updateMany(查询条件,要更新的内容[,配置对象])
-D delete
db.集合名.remove(查询条件)//删除所有年龄小于等于19的学生举例:db.students.remove({age:{$lte:19}})
模块化数据库操作
有一个db专门连接数据库
let mongoose = require('mongoose');mongoose.set('useCreateIndex', true); // 使用一个新的索引创建器
// 1. 连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/dd', {useNewUrlParser: true, // 使用一个新的url解析器,用于解决一些安全性问题useUnifiedTopology: true // 使用一个统一的新的拓扑结构
});
let isConnect = new Promise((resolve, reject) => {// 2. 绑定数据库连接的监听mongoose.connection.on('open', function (err) {if (err) {reject(err);}resolve(true);// 3. 操作数据库})
})module.exports = isConnect
表模型
// 连接数据库,借助第三方工具库
let mongoose = require('mongoose')let Schema = mongoose.Schema; // ----- 引入模式对象let studentRule = new Schema({stu_id: {type: String, // 限制学号必须为字符串required: true, // 限制学号为必填项unique: true, // 限制学号唯一},name: {type: String, // 限制学号必须为字符串required: true, // 限制学号为必填项},age: {type: Number, // 限制学号必须为字符串required: true, // 限制学号为必填项},sex: {type: String, // 限制学号必须为字符串required: true, // 限制学号为必填项},hobby: [String],info: Schema.Types.Mixed,date: {type: Date,default: Date.now(),},enable_flag: {type: String,default: "Y"}
}); // 创建约束对象module.exports = mongoose.model('student', studentRule); // 用于生成某个集合所对应的模型对象 创建模型对象
增删改查
// 连接数据库,借助第三方工具库
let mongoose = require('mongoose')// 引入学生模型
let stuModel = require('./model/studentModel')let db = require('./model/db')
// 判断如果成功,crud
db.then((data) => {stuModel.find({ name: "傻逼" }, function (err, data) {if (err) {console.log(err);return;}console.log(data);})
}, (err) => {console.log(err);
});
Node原生搭建服务器
// 创建一个http
// 引入Node内置的http模块
let http = require('http')
let querystring = require('querystring')// 创建一个服务员 ------- 创建服务对象
let server = http.createServer(function (req, res) {let index = req.url.indexOf('?');let par = req.url.substr(index + 1);console.log(querystring.parse(par));res.setHeader('content-type', 'text/html;charset=utf8')res.end("大傻逼");})// 让服务员开始干活,获取客人点的菜单server.listen(8083, function (err) {!err ? console.log("端口打开", 'http://127.0.0.1:8083') : console.log(err);
})
express框架
1. 下载
yarn add express
2. GET请求
GET http://localhost:3000/index.html?username=sunwukong&password=123123 HTTP/1.1Host: localhost:3000Connection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9
GET http://localhost:3000/hello.html HTTP/1.1:GET请求,请求服务器路径为http://localhost:3000/hello.html,?后面跟着的是请求参数(查询字符串),协议是HTTP 1.1版本
Host: localhost:3000:请求的主机名为localhost,端口号3000
Connection: keep-alive:处理完这次请求后继续保持连接,默认为3000ms
Pragma: no-cache:不缓存该资源,http 1.0的规定
Cache-Control: no-cache: 不缓存该资源 http 1.1的规定,优先级更高
Upgrade-Insecure-Requests: 1:告诉服务器,支持发请求的时候不用http而用https
User-Agent: Mozilla/5.0 (…:与浏览器和OS相关的信息。有些网站会显示用户的系统版本和浏览器版本信息,这都是通过获取User-Agent头信息而来的
Accept: text/html,…:告诉服务器,当前客户端可以接收的文档类型。q 相当于描述了客户端对于某种媒体类型的喜好系数,该值的范围是 0-1。默认为1
Accept-Encoding: gzip, deflate, br:支持的压缩格式。数据在网络上传递时,可能服务器会把数据压缩后再发送
Accept-Language: zh-CN,zh;q=0.9:当前客户端支持的语言,可以在浏览器的工具选项中找到语言相关信息
3. POST请求
lPOST请求要求将form标签的method的属性设置为post
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0USlmfJf-1632482418668)(file:///C:\Users\21727\AppData\Local\Temp\ksohtml7104\wps1.jpg)]
lPOST请求是可以有请求体的,而GET请求没有请求体
POST http://localhost:3000/index.html HTTP/1.1Host: localhost:3000Connection: keep-aliveContent-Length: 34Pragma: no-cacheCache-Control: no-cacheOrigin: http://localhost:3000Upgrade-Insecure-Requests: 1Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Referer: http://localhost:3000/form.htmlAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9Cookie: Webstorm-129da853=8726c2d8-3b88-48b8-8db0-dd82e62fb79a username=sunwukong&password=123123
Origin: http://localhost:3000:请求来源于 http://localhost:3000
Content-Type: application/x-www-form-urlencoded:提交数据的方式
Cookie: Webstorm…:cookie信息
username=sunwukong&password=123123:请求体内容!对应form表单输入的内容
1.3.3 响应报文
1. 报文格式
响应首行;响应头信息;空行;响应体;
2. 报文分析
HTTP/1.1 200 OKX-Powered-By: ExpressAccept-Ranges: bytesCache-Control: public, max-age=0Last-Modified: Wed, 21 Mar 2018 13:13:13 GMTETag: W/"a9-16248b12b64"Content-Type: text/html; charset=UTF-8Content-Length: 169Date: Thu, 22 Mar 2018 12:58:41 GMTConnection: keep-alive <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body> <h1>这是我的第一个服务器</h1></body></html>
HTTP/1.1 200 OK:协议是HTTP 1.1版本,请求响应成功
X-Powered-By: Express:自定义的头,表示用的框架,一般不返回容易造成安全漏洞。
Accept-Ranges: bytes:告诉浏览器支持多线程下载
Cache-Control: public, max-age=0:强制对所有静态资产进行缓存,即使它通常不可缓存。max-age指定多久缓存一次
Last-Modified: Wed, 21 Mar 2018 13:13:13 GMT:这个资源最后一次被修改的日期和时间
ETag: W/“a9-16248b12b64”:请求资源的标记/ID
Content-Type: text/html; charset=UTF-8:返回响应体资源类型
Content-Length: 169:响应体的长度
Date: Thu, 22 Mar 2018 12:58:41 GMT:提供了日期的时间标志,说明响应报文是什么时间创建的
3. 响应状态码
响应码对浏览器来说很重要,它告诉浏览器响应的结果。
200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
301:重定向,被请求的旧资源永久移除了(不可以访问了),将会跳转到一个新资源,搜索引擎在抓取新内容的同时也将旧的网址替换为重定向之后的网址;
302:重定向,被请求的旧资源还在(仍然可以访问),但会临时跳转到一个新资源,搜索引擎会抓取新的内容而保存旧的网址;
304:请求资源未被修改,浏览器将会读取缓存;
404:请求的资源没有找到,说明客户端错误的请求了不存在的资源;
500:请求资源找到了,但服务器内部出现了错误;
1.4 get和post区别
GET使用URL或Cookie传参,而POST将数据放在BODY中。
GET方式提交的数据有长度限制,则POST的数据则可以非常大。
POST比GET相对安全,因为数据在地址栏上不可见。
1.4.1 常见的get请求
url地址栏发送请求
点击a标签发送请求
Form表单没有填写(method: post)时发送的请求
1.4.2 常见的post请求
- Form表单method: post时发送的请求
node.js 从基础到操作数据库相关推荐
- Node.js 连接 MySQL 并进行数据库操作 –node.js 开发指南
Node.js是一套用来编写高性能网络服务器的JavaScript工具包 通常在NodeJS开发中我们经常涉及到操作数据库,尤其是 MySQL ,作为应用最为广泛的开源数据库则成为我们的首选,本篇就来 ...
- Node.js+Mongoose实现MondoDB操作
1.MongoDB是什么,就是一个讲数据存储为类似JSON格式的NoSQL数据库,结构灵活. 2.Mongoose是什么,就是一个以对象形式来操作MongoDB存储的node.js库,ORM,非常方便 ...
- Node.js Stream - 基础篇
背景 在构建较复杂的系统时,通常将其拆解为功能独立的若干部分.这些部分的接口遵循一定的规范,通过某种方式相连,以共同完成较复杂的任务.譬如,shell通过管道|连接各部分,其输入输出的规范是文本流. ...
- 如何使用 Node.js 访问 SAP HANA Cloud 数据库里的数据
登录 SAP Business Technology Platform,找到 space 下自己创建好的 HANA Cloud 实例,右键菜单选择 Copy SQL Endpoint,将 HANA C ...
- Vue.js+Node.js+MySQL的前后端+数据库系统结构
前言: 大三暑假回国实习, 经过了1个月时间的培训学习, 本人渐渐熟悉了实习的工作环境和节奏. 由于我所在的前端APP研发部门使用的是Vue.js框架, 因此我在被分配**[公司官方网站的重制]**任 ...
- Node.js 连接 MySQL 并进行数据库操作
Node.js是一套用来编写高性能网络服务器的JavaScript工具包 代码片段(6) [代码] 安装 node-mysql view source print? 1 $ npm install m ...
- Node.js零基础自学(持续更新中)
1. Node.js时基于Chrome V8 引擎的JavaScript运行环境.官网:Node.jsNode.js® is a JavaScript runtime built on Chrome' ...
- node.js自学基础笔记
Node.js 学习目标 能够知道什么是node.js 能够知道node.js可以做什么 能够说出node.js中javascript的组成部分 能够使用path模块处理模块路径 能够使用http模块 ...
- Node.js框架Express与MySQL数据库的学习笔记
一.数据库的基本概念 1.什么是数据库 数据库(database)是用来组织.存储和管理数据的仓库. 2.常见的数据库及分类 常见的数据库有:MySQL 数据库.Oracle 数据库(收费).SQL ...
最新文章
- asp.net的定义
- 树莓派获4500万美元融资,估值已达5亿美元,去年创下了710万台销量纪录
- 吃万里路 |甜品店大盘点
- rufus linux开机密码,使用Rufus 3.4制作Ubuntu 18.04.1 U盘启动盘的方法
- 贵阳计算机网络技术学院录取分数线,贵阳职业技术学院录取分数线2021是多少分(附历年录取分数线)...
- screenX,clientX,pageX,offsetX,的区别
- python 回溯法 子集树模板 系列 —— 4、数字组合问题
- linux怎么运行idl,科学网—在Scientific linux 7上安装idl83 - 姜小川的博文
- 直播电商源码,实现直播音视频的推流
- 十分钟学懂Python入门基础3(中)
- orcale中like用法详解
- 二叉查找树(BST)专题
- Farmer John 木瓜地 C++
- ocp认证考试报名_大连OCP认证考试中心
- 全国计算机一级与二级的差别,全国计算机一级与二级的区别
- 蓝牙协议规范(射频、基带链路控制、链路管理)
- EasyNVR纯H5摄像机直播解决方案前端解析之:RTSP安防监控实时直播的四分屏的前端展示方案
- 学了深度学习能干什么?飞桨内推岗位大曝光!
- Java图形化界面---进度条
- 园区组网架构详解(CSS、iStack、Eth-Trunk、Smart link)