数据库、MongoDB/Mongoose、cookie与session、密码加密、图片处理、web Socket和Socket.IO框架
一、传统数据库
数据库就是存储数据的,那么存储数据就用txt就行了啊,为什么要有数据库?
- 理由1: 数据库有行、列的概念,数据有关系,数据不是散的。
- 老牌数据库,比如MySQL、SQL Server、Oracle、Access,又叫做结构型数据库。
- 为什么?因为每个表中都有明确的字段,每行记录都有这些字段。不能有的行有,有的行没有。
- 理由2:数据库能够提供非常方便的接口,让增删改查操作变得简单
- 老牌数据库,都使用SQL语言,管理数据库。SQL就是structure query language。
- 理由3:数据库要给PHP、.net、jsp等语言提供接口。用php这些语言,能够向数据库中增删改查。
老牌数据库,都是结构型数据库,现在出了什么问题?
**数据不灵活。一个字段,需要是同样类型的数据。**不能一行记录是文本,一行记录是数字。也不能一行有字段,一行没有
关系表还支持约束
- 唯一的
- 主键
- 默认值
- 非空
非结构型数据库NoSQL应运而生。
NoSQL是个怪胎,无法挑战老牌数据库,但是在大数据时代有自己的意义。
二、NoSQL
特点 | NoSQL分类 | NoSQL数据库适用场景 |
---|---|---|
非结构型数据库 | 键值存储数据库 | 1、数据模型比较简单 |
没有行、列的概念。用JSON来存储数据 | 列存储数据库 | 2、需要灵活性更强的IT系统 |
集合就相当于“表”,文档就相当于“行” | 文档型数据库 | 3、对数据库性能要求较高 |
图形数据库 | 4、不需要高度的数据一致性 | |
5、对于给定key,比较容易映射复杂值的环境 |
三、MongoDB
3.1 基本概念
MongoDB是最像关系型数据库的非关系型数据库
- 数据库 ===》数据库
- 数据表 ===》集合(数组)
- 表记录 ===》(文档对象)
特点:
- 可以有多个数据库
- 一个数据库中可以有多个集合(表)
- 一个集合中可以有多个文档(表记录)
- 文档结构很灵活,没有任何限制
- MongoDB很灵活,不像MySQL一样先创建数据库、表、设计表结构
- 当自动插入数据的时候,只需要指定往哪个数据库的哪个集合操作就可以了
- 一切都由MongoDB来帮助自动完成建库建档
开机命令:mongod --dbpath c:\mongo
--dbpath就是选择数据库文档所在的文件夹。
mongoDB中,有物理文件对应一个个数据库,U盘可以拷贝。
开机这个CMD不能动,不能关,不能ctrl+c。 一旦这个cmd有问题了,数据库就自动关闭了。
所以,应该再开一个cmd。输入 mongo
那么,运行环境就是mongo语法了
命令 | 功能 |
---|---|
mongo
|
使用数据库 |
exit
|
退出连接 |
mongod
|
开机 |
mongoimport
|
导入数据 |
show dbs
|
查看所有数据库列表 |
use 数据库名字
|
新建 / 使用某个数据库 |
db
|
查看当前所在数据库 |
cls
|
清屏 |
db.dropDatabase();
|
删除数据库,删除当前所在的数据库 |
3.2 增删改查
操作 | 示例 | 说明 |
---|---|---|
插入数据 |
db.student.insert({'name': 'aa', 'age': 12})
|
student就是所谓的集合。集合中存储着很多json。 student是第一次使用,集合将自动创建 |
mongoimport --db test --collection restaurants --drop --file primer-dataset.json
|
–db test 往哪个数据库导入 –collection restaurants 往哪个集合中导入 –drop 把集合清空 –file primer-dataset.json 哪个文件 |
|
查找数据 |
db.student.find({"score.shuxue":{$gt:50}, $or:[{"age":9},{"age":11}]})
|
没有参数将列出这个集合的所有文档
|
修改数据 |
db.student.update({"sex":"男"},{$set:{"age":33}},{multi: true});
|
所有男性的年龄改为33岁,{multi: true} 表示更改所有匹配项目,否则只更改单个文档single document
|
db.student.update({"name":"小明"},{"name":"大明","age":16});
|
完整替换,不出现$set关键字 | |
删除数据 |
db.restaurants.remove( { "borough": "Manhattan" } )
|
默认移除匹配的所有文档 |
db.restaurants.remove( { "borough": "Queens" }, { justOne: true } )
|
{ justOne: true } 只移除匹配的一个文档
|
3.3 在Node中如何操作MongoDB数据
3.3.1使用官方的mongodb
包
npm搜安装包:https://www.npmjs.com/package/mongodb
跳转到github:https://github.com/mongodb/node-mongodb-native
有安装与使用规范,太原生了,一般不用
3.3.2 使用第三方mongoose
第三方包:mongoose
基于MongoDB官方的mongodb
包再一次做了封装
网址:https://mongoosejs.com/
四、Mongoose
4.1 概念
是一个将JavaScript对象与数据库产生关系的一个框架,object related model。
操作对象,就是操作数据库了;对象产生了,同时也持久化了。
这个思路是Java三大框架SSH中Hibernate框架的思路。彻底改变了人们使用数据库的方式。
官网:https://mongoosejs.com/
官方指南:https://mongoosejs.com/docs/guide.html
官方API文档:https://mongoosejs.com/docs/api.html
hello world:
var mongoose = require('mongoose'); // 引包,并不需要引用mongodb这个包
mongoose.connect('mongodb://localhost/test', { useMongoClient: true });// 链接数据库,test是数据库名字
mongoose.Promise = global.Promise;
// 创建一个模型,就是在设计数据库
// MongoDB 是动态的,非常灵活,只需要在代码中设计你的数据库就可以了
// mongoose 这个包就可以让你的设计编写过程变的非常的简单
var Cat = mongoose.model('Cat', { name: String });// 创建了一个模型。猫的模型。所有的猫都有名字,是字符串。“类”for (var i = 0; i < 100; i++) {// 实例化一个 Catvar kitty = new Cat({ name: '喵喵' + i });// 持久化保存 kitty 实例kitty.save(function (err) {if (err) {console.log(err);} else {console.log('meow');}});
}
上面的代码中,没有一个语句是明显的操作数据库,感觉都在创建类、实例化类、调用类的方法,都在操作对象,但是数据库同步被持久了。
mongoose的哲学,就是让你用操作对象的方式操作数据库。
4.2 设计Schema发布model
创造schema → 定义一些schema的静态方法 → 创造模型
var mongoose = require('mongoose')
var Schema = mongoose.Schema
// 1.连接数据库
// 指定连接的数据库不需要存在,当你插入第一条数据之后就会自动被创建出来
mongoose.connect('mongodb://localhost/itcast')// 2.设计集合结构(表结构)
// 字段名称就是表结构中的属性名称,约束的目的是为了保证数据的完整性,不要有脏数据
var userSchema = new Schema({username:{type:String,required:true},password:{type:String,required:true},email:{type:String}
})
// 可创建静态方法:userSchema.statics.sayHi = ...// 3.将文档结构发布为模型
// mongoose.model方法就是用来将用一个架构发布为model
// 第一个参数:传入一个大写名词单数字符串用来表示数据库名称
// mongoose会自动将大写名词的字符串生成 小写复数 的集合名称
// 例如这里的 User 最终会变成 users 集合名称
// 第二个参数:架构 Schema
// 返回值:模型构造函数
var User = mongoose.model('User', userSchema);// 4.有了模型构造函数以后,使用这个构造函数对 users 集合中的数据进行操作(增删改查)
什么是静态方法,什么是类方法:
// 类
function Student(){}
// 实例化一个学生
var xiaoming = new Student();
// 实例方法,因为这个sleep方法的执行者是类的实例
xiaoming.sleep();
// 静态方法(类方法),这个方法的执行者是这个类,不是这个类的实例。
Student.findAllBuJiGe();
前台界面:不操作数据库,只操作类!
4.3 增删改查
操作 | 语法 | |
---|---|---|
增加数据 |
var admin = new User({username:'admin'}); admin.save(function(err,ret){...})
|
|
查询所有 |
User.find(callback)
|
如果中间有改过数据,会把更改前后的数据都给显示出来 |
按条件查询所有 |
User.find({username:'admin'},callback)
|
|
按条件查询单个 |
User.findOne({username:'admin'},callback)
|
只查询一个,显示的是对象{},不是数组[] 不带条件的话,显示第一个对象,一般都会带条件的 |
删除数据 |
User.remove({username:'admin'},callback)
|
|
根据条件更新所有 |
Model.update(conditions,doc,[options],[callback])
|
|
根据指定条件更新一个 |
Model.findOneAndUpdate([conditions],[update],[options],[callback])
|
|
根据id更新一个 |
User.findByIdAndUpdate('id',{password:'123'}, callback)
|
五、cookie、session
cookie是在res中设置,req中读取的。第一次访问没有cookie。
cookie的存储大小有限,4k。对用户可见,用户可以禁用、清除Cookie、可以被篡改。
cookie用来制作记录用户的一些信息
HTTP是无状态的协议,所以两次的访问,服务器不能认识到是同一个客户端的访问,就要用cookie来巧妙的解决这个问题。
Session就是利用cookie,实现的“会话”。就是第一次访问的时候,可以在服务器上为这个用户缓存一些信息,别的用户不能看见这个用户的信息。服务器会下发一个秘钥(cookie),客户端每次访问都携带这个秘钥,那么服务器如果发现这个秘钥吻合,就能够显示这个用户曾经保存的信息。
登陆就是用Session来制作的。任何语言的session都是透明的,不会体现cookie机理。
var session = require("express-session");
app.use(session({secret: 'keyboard cat',resave: false,saveUninitialized: true
}))
app.get("/",function(req,res){if(req.session.login == "1"){res.send("欢迎" + req.session.username);}else{res.send("没有成功登陆");}
});
app.get("/login",function(req,res){req.session.login = "1"; // 设置这个sessionreq.session.username = "考拉"res.send("你已经成功登陆");
});
都是使用req对象。
六、加密
永远不要用明码写密码
MD5加密是函数型加密。就是每次加密的结果一定相同,没有随机位。
特点:
不管加密的文字,多长多短,永远都是32位英语字母、数字混合
哪怕只改一个字,密文都会大变
MD5没有反函数破解的可能,网上的破解工具,都是通过字典的模式,通过大量列出明-密对应的字典,找到明码。
两次加密网上也有对应的字典,所以我们不要直接用一层md5,这样对黑客来说和明码一样。
MD5常用于作为版本校验。可以比对两个软件、文件是否完全一致。
node中自带了一个模块,叫做crypto模块,负责加密。
首先创建hash,然后update和digest:
var md5 = crypto.createHash('md5');
var password = md5.update(fields.password).digest('base64');
七、图片处理
http://www.graphicsmagick.org
只要服务器需要处理图片,那么这个服务器就要安装graphicsmagick软件,免费的。
装完之后,可视化工具一点用都没有,从桌面上删除。我们要把安装目录设置为环境变量。
控制台CMD命令:
gm convert a.bmp a.jpg
: 格式转换gm mogrify -resize 320x200 danny.jpg
:更改当前目录下*.jpg的尺寸大小,并保存于目录.thumb里面
node要使用graphicsmagick,需要npm装一个gm的包。
node缩略图的制作:
var fs = require('fs');
var gm = require('gm');
gm('./danny.jpg').resize(50, 50,"!").write('./danny2.jpg', function (err) {if (err) {console.log(err);}}
);
node头像裁切:
gm("./danny.jpg").crop(141,96,152,181).write("./2.jpg",function(err){// 141 96 是宽高 152 181是坐标
});
总结
ejs模式:
// 写服务
app.get("/allstudent", function(req,res,next){db.find("students", {}, function(err,result){// 寻找完毕之后,result就是一个数组,服务已经成功了,但是,界面必须要可视化,所以要有模板引擎呈递res.render("allstudent",{"result" : result;});// 如果不用模板引擎呈递,可以直接输出JSON,前台用Ajax或者Angular调用// var obj = {"result":result};// res.json(obj);});
});
<% for(var i = 0 ; i < result.length ; i++) {%><div class="grid"><p class="title"><%=result[i].name%></p> <p class="xuehao"><%=result[i].xuehao%></p> <p class="sex"><%=result[i].sex%></p> </div>
<%}%>
Ajax模式:
// 写服务
app.get("/allstudent", function(req,res,next){db.find("students",{},function(err,result){// 如果不用模板引擎呈递,可以直接输出JSON,前台用Ajax或者Angular调用var obj = {"result":result};res.json(obj);});
});
======================================
<script type="text/template" id="tem">// 这里是一个underscore模板<div class="grid"><p class="title">{{=name}}</p><p class="xuehao">{{=xuehao}}</p> <p class="sex">{{=sex}}</p> </div>
</script前端页面: jQuery片段:
// 得到模板html
var templateString = $("#tem").html();
// ajax请求
$.get("/allsutdent",function(result){// 这个result就是一个json对象// 要放到页面上,所以为了不字符串拼接,可以用模板引擎underscorefor(var i = 0 ; i < result.result.length ; i++){// 组装模板var compiled = _.compiled(templateString,{"name" : result.result[i].name;"sex" : result.result[i].sex;"xuehao" : result.result[i].xuehao;});// 上DOM$(".liebiao").append($(compiled));}
});
八、web Socket和Socket.IO框架
HTTP无法轻松实现实时应用:
HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接。
我们可以非常轻松的捕获浏览器上发生的事件(比如用户点击了盒子),这个事件可以轻松产生与服务器的数据交互(比如Ajax)。
但是,反过来却是不可能的:服务器端发生了一个事件,服务器无法将这个事件的信息实时主动通知它的客户端。
只有在客户端查询服务器的当前状态的时候,所发生事件的信息才会从服务器传递到客户端。
但是,聊天室确实存在。
解决方法:
长轮询:客户端每隔很短的时间,都会对服务器发出请求,查看是否有新的消息,只要轮询速度足够快,例如1秒,就能给人造成交互是实时进行的印象。这种做法是无奈之举,实际上对服务器、客户端双方都造成了大量的性能浪费。
长连接:客户端只请求一次,但是服务器会将连接保持,不会返回结果(想象一下我们没有写res.end()时,浏览器一直转圈)。服务器有了新数据,就将数据发回来,又有了新数据,就将数据发回来,而一直保持挂起状态。这种做法的也造成了大量的性能浪费。
WebSocket
8.1 WebSocket
WebSocket协议能够让浏览器和服务器全双工实时通信,互相的,服务器也能主动通知客户端了。
● 原理:利用HTTP请求产生握手,HTTP头部中含有WebSocket协议的请求,所以握手之后,二者转用TCP协议进行交流(QQ的协议)。现在的浏览器和服务器之间,就是QQ和QQ服务器的关系了。
所以WebSocket协议,需要浏览器支持,更需要服务器支持。
● 支持WebSocket协议的浏览器有:Chrome 4、火狐4、IE10、Safari5
● 支持WebSocket协议的服务器有:Node 0、Apach7.0.2、Nginx1.3
Node上需要写一些程序,来处理TCP请求。
● Node从诞生之日起,就支持WebSocket协议。不过,从底层一步一步搭建一个Socket服务器很费劲(想象一下Node写一个静态文件服务都那么费劲)。所以,有大神帮我们写了一个库Socket.IO。
8.2 Socket.IO
Socket.IO是业界良心,新手福音。
- 屏蔽了所有底层细节,让顶层调用非常简单。
- 还为不支持WebSocket协议的浏览器,提供了长轮询的透明模拟机制。
Node的单线程、非阻塞I/O、事件驱动机制,使它非常适合Socket服务器。
网址:http://socket.io/
下载库:npm install socket.io
写原生JS,搭建一个服务器,server创建好之后,创建一个io对象
var http = require("http");
var server = http.createServer(function(req,res){res.end("你好");
});
var io = require('socket.io')(server);
// 监听连接事件
io.on("connection",function(socket){console.log("1个客户端连接了");
})
server.listen(3000,"127.0.0.1");
写完这句话之后,你就会发现,http://127.0.0.1:3000/socket.io/socket.io.js 就是一个js文件的地址了。
现在需要制作一个index页面,这个页面中必须引用秘密js文件。调用io函数,取得socket对象。
<h1>我是index页面,我引用了秘密script文件</h1>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">var socket = io();
</script>
此时,在服务器上,app.js中就要书写静态文件呈递程序,能够呈递静态页面。
var server = http.createServer(function(req,res){if(req.url == "/"){// 显示首页fs.readFile("./index.html",function(err,data){res.end(data);});}
});
至此,服务器和客户端都有socket对象了。
每一个连接上来的用户,都有一个socket。 由于我们的emit语句,是socket.emit()
发出的,所以指的是向这个客户端发出语句。
广播,就是给所有当前连接的用户发送信息:
// 创建一个io对象
var io = require('socket.io')(server);
// 监听连接事件
io.on("connection",function(socket){console.log("1个客户端连接了");socket.on("tiwen",function(msg){console.log("本服务器得到了一个提问" + msg);io.emit("huida","吃了");});
});
复习顺序
Node.js特点:单线程、异步I/O(非阻塞I/O)、事件驱动(事件环)
适合的程序:就是没有太多的计算,I/O比较多的业务。举例:留言本、考试系统、说说、图片裁切服务器
Node.js原生: http、fs、path、url。 静态服务、简单路由、GET、POST请求。
模块:formidable、gm、express
Express:中间件、MVC建站、模板引擎ejs、静态服务、简单路由、GET、POST请求、MD5加密、图片上传。
服务器的一些概念:Cookie、Session
持久化NoSQL: 非关系型数据库,Not Only SQL。
- 特点:没有schema,没有行和列。用文档(JSON)来存储。
MongoDB:安装、开启、导入数据、Shell管理数据库、Mongo Vue、Node.js做CRUD(增删改查)、DAO层的封装、索引、操作符$set $lt $gt $push $pull
Mongoose: ODM,不用直接操作数据库,操作对象,这个对象自动持久。
Defining your schema 定义文档结构
schema定义的时候,支持的类型:String、Number、Date、Buffer、Boolean、Mixed、ObjectId、Array
转换为对象:mongoose.model(modelName, schema):
定义对象(实例)方法:
// define a schema
var animalSchema = new Schema({ name: String, type: String });
// assign a function to the "methods" object of our animalSchema
animalSchema.methods.findSimilarTypes = function (cb) {return this.model('Animal').find({ type: this.type }, cb);
}
虚拟属性:
// define a schema
var personSchema = new Schema({name: {first: String,last: String}
});
// compile our model
var Person = mongoose.model('Person', personSchema);
// create a document
var bad = new Person({name: { first: 'Walter', last: 'White' }
});
数据库、MongoDB/Mongoose、cookie与session、密码加密、图片处理、web Socket和Socket.IO框架相关推荐
- jdbc mysql 解密_数据库配置文件jdbc.properties 实现用户名密码加密
项目框架:spring 我们在开发应用时,需要连接数据库,一般把数据库信息放在一个属性配置文件中,比如jdbc.properties,具体的内容 jdbc.properties配置文件 jdbc.ur ...
- Django框架详细介绍---cookie、session、自定义分页
1.cookie 在HTTP协议介绍中提到,该协议是无状态的,也就是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的 ...
- Django Cookie于Session
一.Cookie与Session由来 因为Http协议的特性,每一次来自用户浏览器的请求都是无状态且独立的,通俗地说,就是无法保存用户状态,后台服务器根本就不知道当前请求和以前及以后请求是否来自同一用 ...
- 做web开发,怎么能不懂cookie、session和token呢?
如果把人体比作一个web系统的话,cookie.session和token就好像人体的经络和血管一样,而web系统中的数据,就好像人体的血液一样.血液依靠着血管在人体内流动,就如数据根据cookie和 ...
- 用户密码和cookie,session、token还有AKSK
背景:认证.授权.鉴权和权限控制: https://segmentfault.com/a/1190000013258488 认证.授权.鉴权和权限控制 | 滩之南 单点登录的通用架构实现 | 滩之南 ...
- WeChat授权Token验证体系:用token来隐藏微信用户的openid不用用户名与密码了, 与cookie与session很相似
背景: 有些接口是可以公开访问的,有些是不允许公开访问的,所以要设置token进行区分验证 之前的网站是使用用户与密码,利用cookie与session进行验证用户态: 现在的话,是app和小程序,一 ...
- 使用session保持登录状态,cookie保存用户账号密码
session保存登录状态与cookie保存账号密码 1. session维持登录状态 1.1 代码实现 2. cookie保存账号密码 2.1 什么是cookie 2.2 cookie记住账号密码 ...
- BCrypt加密怎么存入数据库_Spring Boot 中密码加密的两种姿势
1.为什么要加密 2.加密方案 3.实践3.1 codec 加密3.2 BCryptPasswordEncoder 加密 4.源码浅析 先说一句:密码是无法解密的.大家也不要再问松哥微人事项目中的密码 ...
- php登录实现session记住密码,利用php实现一周之内自动登录存储机制(cookie、session、localStorage)...
cookie.session.localStorage这三个应该是最让程序员头疼的了,我利用简单的登录界面的username和password来说明一下吧. 1.cookie用来存储用户相关数据,存储 ...
最新文章
- 商显行业高速发展,如何开启全新商务会议时代
- 一款名为Blue_Moon的后台模板的初步研究
- 爬取百度知道分类_百度指数爬虫|介绍篇
- 知识点讲解三:获取重定位后的网址
- anaconda python2.7,安装在windows中的Python 2.7 Anaconda2
- 浅谈AQS(AbstractQueuedSynchronizer,同步队列)
- mysql资质_MySQL语句与Java代码实现按需过滤企业员工的资质证书
- Android之使用AlertDialog类和AlertDialog.Builder类创建带取消,确定,中立的对话框
- [BZOJ5286][HNOI2018]转盘(线段树)
- linux opencv移植教程,OpenCV在Ubuntu和Linux系统下的移植
- java中创建对象的方式有哪些,Java中创建对象的四种方式
- 普通程序员想转人工智能,不知道它?别想了!
- oracle asm文件查找,Oracle ASM 文件管理
- 学计算机猝死,北京邮电大学计算机系一名学生球场踢球时猝死
- 服务器c盘临时文件在哪里,excel在c盘哪个文件夹|excel临时文件位置
- linux卸载windows boot,windows和Linux双系统卸载Linux系统
- 这个是什么错误,求大神解答
- 【一步一步教会您升级到win7旗舰版】
- 大数据可视化管理antV使用详解
- vim-python怎么用_技术|如何在使用 Vim 时访问/查看 Python 帮助