mongoose操作mongodb

http://mongoosejs.com/docs/api.html#index-js
mongoose是nodejs环境下操作mongodb的模块封装,使用mongoose之后,实际上只需要在mongodb中创建好数据库与用户,集合的定义、创建、操作等直接使用mongoose即可。

  • 一、连接
  • 二、重要概念
  • 三、基本操作
    • 1、Schema
    • 2、Model
    • 3、实例化document
    • 4、保存数据
    • 5、文档查询
    • 6、文档更新
    • 7、文档删除
    • 8、自定义方法
    • 9、虚拟属性
    • 10、前置与后置钩子

一、连接

let mongoose = require('mongoose');//连接mongodb
//非auth模式
//mongoose.connect('mongodb://localhost:27017/mall');
//auth模式
/**
mongodb 为协议
第一个mall: 连接数据库的用户名
123456: 用户的密码
localhost: mongodb地址
27017: mongodb端口号
第二个mall: 数据库名字
**/
mongoose.connect('mongodb://mall:123456@localhost:27017/mall');//连接失败
mongoose.connection.on('connected',() => {console.log('mongodb connected!');
});//连接成功
mongoose.connection.on('error',(err) => {console.log('mongodb connect fail:'+err);
});//连接断开
mongoose.connection.on('disconnected',() => {console.log('mongodb connect disconnected!');
});// connection的事件列表可查看:http://mongoosejs.com/docs/api.html#connection_Connection
// 或 ./node_modules/mongoose/lib/connection.js#Connection()// 关闭的两种方式
// mongoose.connection.close(); 等同于 db.close();
// mongoose.disconnect();

二、重要概念

moog
  Mongooose中,有三个比较重要的概念,Schema、Model、Document。Schema生成Model,Model实例化成为Document。

  Schema用于定义数据库的结构。类似创建表时的数据定义(不仅仅可以定义文档的结构和属性,还可以定义文档的实例方法、静态模型方法、复合索引等),每个Schema会映射到mongodb中的一个collection,Schema不具备操作数据库的能力。

  Model是由Schema编译而成的构造器,具有抽象属性和行为,可以对数据库进行增删查改。Model的每一个实例(instance)就是一个文档document。

  Document是new Model后创建的实例,它的操作会影响数据库。

三、基本操作

1、Schema

Schema是对mongodb中某个集合的结构描述,它定义一个集合中应该包含哪些数据项,每个数据项的数据类型与检查约束。可以想象成一个抽象类,只有定义,没有实现。就是规定好某个集合的框架应该是怎么样的。也可以理解是mysql中的表结构。
可以为数据项指定的数据类型有8种:

String      字符串
Number      数字    
Date        日期
Buffer      二进制
Boolean     布尔值
Mixed       混合类型
ObjectId    对象ID    
Array       数组

创建Schema

const mongoose = require('mongoose')
//获取Schema
const Schema = mongoose.Schema;//声明一个Schema实例,实际就是创建一个集合的结构框架
let animalSchema = new Schema({title: String, //类型可以是首字母大写age: 'number', //类型也可以写成字符串全小写food: [{ //数组name: String}]
});//如果需要为animalSchema增加属性,可以使用add
animalSchema.add({sex: {type: String,enum: ['male', 'female'] //规定,字段值为枚举约束,只能填male/female}
});

创建Schema时可以有一系列的约束条件,类似mysql中字段的非空、唯一等约束。
基本语法是:

{name: {type:String, validator:value}}

常用的约束有:

required: 数据必须填写
default: 默认值
min: 最小值(只适用于数字)
max: 最大值(只适用于数字)
match: 正则匹配(只适用于字符串)
enum:  枚举匹配(只适用于字符串)
validate: 自定义匹配

其中validate是自定义约束
例如要自定义检查长度

// 自定义长度检查
let lengthValidate = (param) => {return param.length <= 10
};//如果需要为animalSchema增加属性,可以使用add
animalSchema.add({sex: {type: String,enum: ['male', 'female'], //规定,字段值为枚举约束,只能填male/femalevalidate: lengthValidate}
});

2、Model

model是根据Schema定义的结构框架生成一个映射mongodb的数据模型,可以把它理解是一个类,是根据Schema创建的一个类,他的数据结构是依据Schema生成的,这个类用来生成document实例。

//通过schema构建model,第一个参数是给model起个名字,第二个参数是构造这个model所依据的schema
let animalModel = mongoose.model('animalModel', animalSchema);

3、实例化document

document是相当于是mongodb中的每一条数据了,它是通过new一个model得到的。

  // 通过实例化model得到document,document的数据项需根据schema定义的结构来写// 通过实例化model得到document,document的数据项需根据schema定义的结构来写let cat = new animalModel({title: '猫咪',food: [{name: '鱼'},{name: '火腿'}],sex: 'male'});

到这一步,mongodb中还没有animalMode集合以及数据。
这里写图片描述

4、保存数据

  • 1、save()
    在mongoose中保存数据,实际就是保存某个document,document通过model实例化来创建。document的save()方法可以将document映射保存到mongodb中,save()方法中可以传递一个回调函数作为参数。因为是在document上调用,自然一次只保存一条文档。
    方法原型:
save(function (err, document) {}) //回调函数中第二个参数是使用保存的数据形成的对象

保存cat:

//保存document,映射成为一条记录
cat.save((err, catObj) => {if (err) {console.log('保存失败');console.info(err);}  else {console.info(catObj);}
});

保存后打印:

{ title: '猫咪',food: [ { name: '鱼', _id: 5a96555e95f678530054f918 },{ name: '火腿', _id: 5a96555e95f678530054f917 } ],sex: 'male',_id: 5a96555e95f678530054f919,__v: 0 }

保存后这个回调中的第二个参数就被填充好值,其中的主键_id也在其中,__v是mongoose用来管理数据版本号的标识,自己不用动。
这时看mongodb中已有集合,集合中已经有一条数据(文档)了。
这里写图片描述
注意:
1、从上图可以看出来,集合的名字是根据mongoose.model('animalModel', animalSchema)中第一个参数来的,变成小写且复数形式,如果结尾是数字则不变。比如这个地方如果第一个参数给的是’animal’,则生成的集合名称就应该是’animals’。
2、在mongoose中操作mongodb,因为有了schema、model、ducument的概念,就不是像mysql一样,事先创建好表结构,而是根据数据结构设计,在代码中声明好schema,再生成model、创建document,进行数据操作。

  • 2、create()
    和save()不一样的是,create()不是在document上调用的,而是在model上调用的,并且可以一次保存多条文档。
    接着用上面的animalModel,这次不去new它了,也就是不去操作document了,直接用mongoose.model出来的model。同时保存两条狗。
    let dog1 = {title: '1号狗狗',food: [{name: '骨头'},{name: '肉肉'},],sex: 'male'};let dog2 = {title: '2号狗狗',food: [{name: '骨头'},{name: '肉肉'},],sex: 'male'};animalModel.create(dog1, dog2, (err, rsObj1, rsObj2) => {if (err) {console.log('保存失败');console.info(err);} else {console.log('保存成功');console.info(rsObj1);console.info(rsObj2);}});

打印的结果:

保存成功
{ title: '1号狗狗',food: [ { name: '骨头', _id: 5a96607b5ce650532494f010 },{ name: '肉肉', _id: 5a96607b5ce650532494f00f } ],sex: 'male',_id: 5a96607b5ce650532494f011,__v: 0 }
{ title: '2号狗狗',food: [ { name: '骨头', _id: 5a96607b5ce650532494f013 },{ name: '肉肉', _id: 5a96607b5ce650532494f012 } ],sex: 'male',_id: 5a96607b5ce650532494f014,__v: 0 }

再看看mongodb中:
这里写图片描述
注意:这里也验证了一个问题,就是如果model对应的集合已经存在于mongodb中了,则会直接往这个集合中添加文档,如果还没有,则会创建集合。所以在上面保存猫咪的时候,同时创建了集合与添加猫咪文档,而这里的狗狗,直接添加文档。

  • 3、insertMany()
    insertMany()也是model的方法,一次插入多条数据,注意回调中的返回值是所有结果对象的数组。
    let monkey1 = {title: '1号猴猴',food: [{name: '香蕉'},{name: '桃'},],sex: 'male'};let monkey2 = {title: '2号猴猴',food: [{name: '香蕉'},{name: '桃'},],sex: 'male'};animalModel.insertMany([monkey1, monkey2], (err, rsArr) => {if (err) {console.log('保存失败');console.info(err);} else {console.log('保存成功');console.info(rsArr);}});

打印结果:

保存成功
[ { title: '1号猴猴',food: [ [Object], [Object] ],sex: 'male',_id: 5a967c3f44d6d753b6cd6354,__v: 0 },{ title: '2号猴猴',food: [ [Object], [Object] ],sex: 'male',_id: 5a967c3f44d6d753b6cd6357,__v: 0 } ]

5、文档查询

mongodb中的数据查询就是查文档。

  • 1、find()
    find()是用在model上的,这一点很容易理解,既然是查询数据,那么当前肯定是不明确要得到的文档结果是怎样的,方法也就不会在document上。
    find()方法在官方文档中的描述是:
Model.find()Parameters [callback] «Function»
Returns:«Query»Finds documents
The conditions are cast to their respective SchemaTypes before the command is sent.Example:
// named john and at least 18
MyModel.find({ name: 'john', age: { $gte: 18 }});// executes immediately, passing results to callback
MyModel.find({ name: 'john', age: { $gte: 18 }}, function (err, docs) {});// name LIKE john and only selecting the "name" and "friends" fields, executing immediately
MyModel.find({ name: /john/i }, 'name friends', function (err, docs) { })// passing options
MyModel.find({ name: /john/i }, null, { skip: 10 })// passing options and executing immediately
MyModel.find({ name: /john/i }, null, { skip: 10 }, function (err, docs) {});// executing a query explicitly
var query = MyModel.find({ name: /john/i }, null, { skip: 10 })
query.exec(function (err, docs) {});// using the promise returned from executing a query
var query = MyModel.find({ name: /john/i }, null, { skip: 10 });
var promise = query.exec();
promise.addBack(function (err, docs) {});

官方示例find的用法非常清晰了,find方法最简的参数是只给一个回调函数,表示查询所有结果,相当于是sql中的select * from 表名。
find()方法返回值是query对象,query对象有exec和一系列方法,exec()可以执行准备好的find()查询,回调得到结果。

回到animal示例中:
查询animalmodels集合中所有的文档:

//方式一:
animalModel.find((err, rs) => {if (err) {console.log('查询失败');console.info(err);} else {console.log('查询成功');console.info(rs);}});//方式二:let animalQuery = animalModel.find();animalQuery.exec((err, rs) => {if (err) {console.log('查询失败');console.info(err);} else {console.log('查询成功');console.info(rs);}});//两种方式的结果是一样的,返回的rs是一个包含集合中所有文档的数组

find()的完整参数列表是:
Model.find([查询条件], [返回字段列表], [设置选项], [回调函数]);
对于第一个参数,比如age: { $gte: 18 },表示要查询年龄大于等于18的文档。常用的条件操作符有:

$lt$lte$gt$gte$in$nin$eq$ne$or(model.find({$or:[{ color: 'red' }, { status: 'emergency' }]}))、$and$not$nor$exits(值是否存在,model.find({name:{$exits:true}}))、$all(通常用来匹配数组里面的键值,匹配多个值(同时具有) $all:[“apple”,“banana”,“peach”]})、$size(用来查询数组的长度值 model.find({name:{$size:3}}); 匹配name的数组长度为3

有一个特殊的操作符$where,可以灵活的设置查询条件,$where后可以直接写任何的js作为查询条件,但实际上完全可以使用model.where()方法来代替,where()会更加方便。

{$where:"this.x == this.y"}
{$where:function(){return obj.x !== obj.y;
}}

这些操作符在find的第一个参数中使用,query中也有一一对一个的方法。

对于第二个参数,可以设置要返回的字段列表,{name:1,_id:0}表示返回name字段,不返回_id字段。

对于第三个参数,官方示例中用到了一个skip,还有limit、sort。

除了find()外,还有findById()、findOne(),与find的用法都是一样的。只不过findById的第一个参数是准确的id值。这两个方法都只返回一条文档。

  • 2、where()
    官网上这么介绍的
Model.where()
Parameters [val] «Object» optional valueReturns:«Query» 
Creates a Query, applies the passed conditions, and returns the Query.

官方示例:

User.find({age: {$gte: 21, $lte: 65}}, callback);
等同于
User.where('age').gte(21).lte(65).exec(callback);

因为where返回的是query对象,所以可以链式调用:

User
.where('age').gte(21).lte(65)
.where('name', /^b/i)
... etc

所以在实际的使用过程中,用query对象来进行查询是比较方便的,用find()的返回值query链式调用其他方法,或者用where()的返回值query链式调用其他方法,最后用exec(callback)得到结果,这样比较清晰。query有一系列的方法,异步官方文档。

  • 3、query常用方法
sort     排序
skip     跳过
limit    限制
select   显示字段
exect    执行
count    计数
distinct 去重

关于分页与排序,query的三个方法:
query.limit(20); //只返回前20个内容
query.skip(2); //跳过多少条,实际就是开始的索引
query.sort({name:1,age:-1}); //1升序,2降序

6、文档更新

  • 1、update()
    Model.update(conditions, doc, [options], [callback])
    第一个参数conditions为查询条件,第二个参数doc为需要修改的数据,第三个参数options为控制选项,第四个参数是回调函数。
    options有以下选项:
    safe (boolean): 默认为true。安全模式。upsert (boolean): 默认为false。如果不存在则创建新记录。multi (boolean): 默认为false。是否更新多个查询记录。runValidators: 如果值为true,执行Validation验证。setDefaultsOnInsert: 如果upsert选项为true,在新建时插入文档定义的默认值。strict (boolean): 以strict模式进行更新。overwrite (boolean): 默认为false。禁用update-only模式,允许覆盖记录。

把名字叫猫咪的文档的名字更新成猫猫:

    animalModel.update({title :{$eq: '猫咪'}}, {title: '猫猫'}, (err, rs) => {if (err) {console.log('更新失败');console.info(err);} else {console.log('更新成功');console.info(rs);}});

如果不设置multi的话,即使有多条符合条件的文档,也只更新一条。
如果设置options里的upsert参数为true,若没有符合查询条件的文档,mongo将会综合第一第二个参数向集合插入一个新的文档。

  • 2、updateMany()
    updateMany()与update()的区别是更新多个文档,即使设置{multi:false}也更新多个。

  • 3、updateOne()
    updateOne()只更新找到的第一条数据,即使设置{multi:true}只更新一个。

  • 4、数组更新
    update第二个参数,实际可以写成{$set: {title: '猫猫'}}$set操作符表示设值,如果要更新的是数组,可以有以下操作符:

$addToSet  // 当且仅当待添加到数组的元素是当前数组所没有时,才会去添加
$pop       // 当指定数组的修饰符值为-1时,删除该数组的第1个元素;当值为1时,删除最后一个元素
$pull      // 删除指定查询条件下的数组元素
$pullAll   // 删除数组中符合给定的集合的值的所有元素,与$pull的区别于目标删除元素是被逐一列举出来的
$push      // 将元素添加到指定的数组中

给猫添加一个食物:

    animalModel.update({title :{$eq: '喵星人'}},{$addToSet:{food: {name: '蛋黄派'}}},(err,rs) =>{if (err) {console.info("保存失败");console.info(err);} else {console.info("保存成功");console.info(rs);}});

结果:

保存成功
{ n: 1, nModified: 1, ok: 1 }
  • 5、其他
    关于其他更新方法还有findOneAndUpdate()、findByIdAndUpdate()。
    通过查询+保存操作也可以实现更新,查询的结果实际是一个document对象,调用save方法,猜想是通过_id与_v来进行的比对,将直接更新本条记录。
animalModel.where('title').eq('猫猫').exec((err, rs) => {if (err) {console.info(err);} else {console.info(rs);rs.forEach(function(item,index,array){item.title = "喵星人";item.save((err,rs) =>{if (err) {console.info("保存失败");console.info(err);} else {console.info("保存成功");console.info(rs);}});});}});

7、文档删除

  • 1、remove()
    remove方法存在两个位置,一个是model上,一个是ducument上,model上就是根据条件去删除集合内某些文档,文档上就是删除自己。
model.remove(conditions, [callback])
document.remove([callback])

示例:

 //model删除animalModel.remove({title :{$eq: '喵星人'}},(err,rs) =>{if (err) {console.info("删除失败");console.info(err);} else {console.info("删除成功");console.info(rs);}});//document删除animalModel.where('title').eq('2号猴猴').exec((err, rs) => {if (err) {console.info(err);} else {console.info(rs);rs.forEach(function(item,index,array){item.remove((err,rs) =>{if (err) {console.info("删除失败");console.info(err);} else {console.info("删除成功");console.info(rs);}});});}});
  • 2、findOneAndRemove()
    model的remove()会删除符合条件的所有数据,如果只删除符合条件的第一条数据,可以使用model的findOneAndRemove()方法
Model.findOneAndRemove(conditions, [options], [callback])
  • 3、findByIdAndRemove()
    通过id删除文档
Model.findByIdAndRemove(id, [options], [callback])
  • 4、其他
    所有删除方法的回调函数都不能省略,否则不成功。要么写在方法的回调函数参数中,如果不写回调函数参数,则可以在最后调用.exec()。

8、自定义方法

mongoose中可以利用已有的api,自定义自己的方法来处理特定的业务需要。

  • 1、实例方法
    通过new model得到的document实例有很多增删改查的方法,如上面的save()方法用来保存文档,我们可以给实例增加自定义方法来实现特定的业务逻辑,增加之后就可以像调用save一样来调用自己的方法,给document增加自定义方法是通过扩展Schema的methods属性来完成的。

为animalSchema扩展document实例方法:

//为document实例添加eat方法,返回所有喜欢吃的食物
animalSchema.methods.eat = function () {let foodList = this.food;let foodStr = '';foodList.forEach(function (item, index, arr) {if (index == 0) {foodStr += item.name;} else {foodStr += ","+item.name;}});return foodStr;
};

document实例调用:

    animalModel.findById('5a96607b5ce650532494f011').exec((err, rs) => {if (err) {console.info("查询失败");console.info(err);} else {console.info("查询成功");console.info(rs);let eatStr =  rs.eat();console.info(eatStr); //骨头,肉肉}});
  • 2、静态方法
    静态方法,是不需要实例化得到document,而是直接在model上调用的方法。
    所以,实例方法,是操作文档(mongodb中的某一条记录)数据用的,静态方法是操作集合用的。

为animalSchema添加静态方法:

//为model添加findDogs方法
animalSchema.statics.findDogs = function (backfun){this.find({title: /狗/}).exec(backfun);
};

model调用:

    animalModel.findDogs((err, rs) => {if (err) {console.info("查询失败");console.info(err);} else {console.info("查询成功");console.info(rs); //打印出两条狗的document}});

-3、查询方法
扩展schema对象的query属性,给model添加查询方法,主要为了扩展query的个性化方法需要。

//为query添加findMonkey方法
animalSchema.query.findMonkey = function (backfun){this.find({title: /猴/}).exec(backfun);
};

query调用:

    let rsQuery = animalModel.find();rsQuery.findMonkey((err, rs) => {if (err) {console.info("查询失败");console.info(err);} else {console.info("查询成功");console.info(rs); //打印出一只猴子的document}});

9、虚拟属性

schema上除了可以设置方法以外,还可以设置虚拟属性,就像vue的getter一样,实际数据库中没有这个属性,但可以通过虚拟属性机制自定义一个经过处理的值,虽然用方法同样能实现,但虚拟属性效率更高。

//添加虚拟属性nameAndSex
animalSchema.virtual('info').get(function () {return this.title + "," +this.sex;
});

调用:

    animalModel.find({title: /狗/}).exec((err, rs) => {if (err) {console.info("查询失败");console.info(err);} else {console.info("查询成功");rs.forEach( function (item, index, arr) {console.info(item.info);});}});

打印结果:

1号狗狗,male
2号狗狗,male

10、前置与后置钩子

通过schema可以为指定的某些方法添加前置钩子函数与后置钩子函数。前置钩子函数在指定方法开始前调用,后置钩子函数不是在指定方法结束后操作,二是在指定方法开始前的最后一步操作。
前置钩子是pre()
后置钩子是post()

//为find方法指定前置操作1
animalSchema.pre('find', function (next) {console.info('前置操作1');next();
});//为find方法指定前置操作2
animalSchema.pre('find', function (next) {console.info('前置操作2');next();
});//为find方法指定后置操作1
animalSchema.post('find', function () {console.info('后置操作1');
});//为find方法指定后置操作2
animalSchema.post('find', function () {console.info('后置操作2');
});

调用find()方法

    animalModel.find({title: /狗/}).exec((err, rs) => {if (err) {console.info("查询失败");console.info(err);} else {console.info("查询成功");console.info(rs);}});

得到打印结果:

前置操作1
前置操作2
后置操作1
后置操作2
查询成功
[ { food: [ [Object], [Object] ],_id: 5a96607b5ce650532494f011,title: '1号狗狗',sex: 'male',__v: 0 },{ food: [ [Object], [Object] ],_id: 5a96607b5ce650532494f014,title: '2号狗狗',sex: 'male',__v: 0 } ]

注意,前置钩子中有一个next函数,如果方法内不调用next(),被设置前置钩子的方法(比如find())执行到钩子时不会继续向下执行。

可以添加前后钩子的方法有:

init
validate
save
remove
count
find
findOne
findOneAndRemove
findOneAndUpdate
insertMany
update

以上是mongoose的常用基本操作,还有索引、聚合等等操作需要积累补充。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac下iterm配色、半透明与样式设置

主要为了实现命令行颜色高亮与整个命令窗口半透明效果。 1、配色主题包下载 1、http://iterm2colorschemes.com/ 下载后解压&#xff0c;到iterm2中&#xff0c;左上角iTerm2->preferences->Profiles&#xff0c;右侧面板找到Colors选项&#xff0c;右下角展开Color Pr…

一个 Dubbo 服务启动要两个小时

前几天在测试环境碰到一个非常奇怪的与 dubbo 相关的问题&#xff0c;事后我在网上搜索了一圈并没有发现类似的帖子或文章&#xff0c;于是便有了这篇。 希望对还未碰到或正在碰到的朋友有所帮助。 现象 现象是这样的&#xff0c;有一天测试在测试环境重新部署一个 dubbo 应用的…

表单提交enctype参数详解之:application/x-www-form-urlencode和multipart/form-data

application/x-www-form-urlencode 我们在提交表单的时候&#xff0c;form表单参数中会有一个enctype的参数。enctype指定了HTTP请求的Content-Type。 默认情况下&#xff0c;HTML的form表单的enctypeapplication/x-www-form-urlencoded。 application/x-www-form-urlencoded是…

内网端口映射工具

由于开发微信需要一个公网域名&#xff0c;需要将本地端口映射到外网域名&#xff0c;最热的工具是ngrok&#xff0c;但被微信屏蔽了&#xff0c;这里使用的是natapp&#xff0c;环境是mac&#xff0c;windows下可使用nat123、花生壳等工具实现同样功能。 简单记录一下过程。 …

iOS----------iPhone导出手机所有短信

第一步&#xff1a;手机连接到itunes 选择本电脑备份 备份的时候不要加密 然后立即备份 第二步&#xff1a;前往文件夹&#xff0c;找到itunes的备份路径~/Library/Application Support/MobileSync/Backup 在这目录下搜索 3d0d开头的文件&#xff0c;这就是 iPhone 短信的…

跨站点脚本(XSS)

1. 简介 跨站点脚本(XSS)是当前web应用中最危险和最普遍的漏洞之一。安全研究人员在大部分最受欢迎的网站,包括Google, Facebook, Amazon, PayPal等网站都发现这个漏洞。如果你密切关注bug赏金计划,会发现报道最多的问题属于XSS。为了避免跨站脚本,浏览器也有自己的过滤器,但安…

CSRF攻击原理及防御

CSRF攻击原理及防御 一、CSRF攻击原理 CSRF是什么呢&#xff1f;CSRF全名是Cross-site request forgery&#xff0c;是一种对网站的恶意利用&#xff0c;CSRF比XSS更具危险性。想要深入理解CSRF的攻击特性我们有必要了解一下网站session的工作原理。   session我想大家都不…

H3C FTP配置示例

转载于:https://www.cnblogs.com/fanweisheng/p/11156596.html

windows10系统下MongoDB的安装及环境配置

windows10系统下MongoDB的安装及环境配置&#xff1a; MongoDB的安装 下载地址&#xff1a; https://www.mongodb.com/download-center (这是windows10环境下的教程&#xff01;请注意&#xff01;) 下载后&#xff0c;我们点击mongodb-win32-x86_64-2008plus-ssl-3.4.3-signed…

CSS clip:rect矩形剪裁功能

CSS中有一个属性叫做clip&#xff0c;为修剪&#xff0c;剪裁之意。配合其属性关键字rect可以实现元素的矩形裁剪效果。此属性安安稳稳地存在于CSS2.1中&#xff0c;且使用上基本上没有类似于max-height/display:table-cell等浏览器的兼容性问题。 根据Dreamweaver的自动提示&a…

Node.js 部署免费/自动续订 HTTPS

统计了使用 Chrome 浏览器&#xff0c;访问的站点统计中&#xff0c;HTTPS 使用率的增长情况&#xff1a;而在今年 2 月份&#xff0c;Chrome 团队也宣布&#xff0c;将在 2018 年 7 月份发布的 Chrome 68 中&#xff0c;将没有部署 HTTPS 的网站标记为 "不安全"。简…

MVVM原理还你

众所周知当下是MVVM盛行的时代&#xff0c;从早期的Angular到现在的React和Vue&#xff0c;再从最初的三分天下到现在的两虎相争。 无疑不给我们的开发带来了一种前所未有的新体验&#xff0c;告别了操作DOM的思维&#xff0c;换上了数据驱动页面的思想&#xff0c;果然时代的进…

CSS页面布局解决方案大全

前端布局非常重要的一环就是页面框架的搭建&#xff0c;也是最基础的一环。在页面框架的搭建之中&#xff0c;又有居中布局、多列布局以及全局布局&#xff0c;今天我们就来总结总结前端干货中的CSS布局。 居中布局 水平居中 1&#xff09;使用inline-blocktext-align&#xff…

AES加密算法的学习笔记

AES简介高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。 对称加密算法也就是加密和解密用相同的密钥&#xff0c;具体的加密流程如下图&#xff1a; 下面简单介绍下各个部分的作用与意义&#xff1a; 明文P没…

前端 crypto-js aes 加解密

背景 前段时间公司做项目&#xff0c;该项目涉及到的敏感数据比较多&#xff0c;经过的一波讨论之后&#xff0c;决定前后端进行接口加密处理&#xff0c;采用的是 AES BASE64 算法加密~ 网上关于 AES 对称加密的算法介绍看上一篇&#xff01; 具体实现 其实搞懂了是怎么一回事…

随笔记录(2019.7.10)

1、ISO/OSI 网络七层参考模型 物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 2、 TCP/IP 网络四层模型和五层模型 四层模型&#xff1a; 网络接口层 网络层 传输层 应用层 五层模型&#xff1a; 物理层 数据链路层 网络层 传输层 应用层 3、 协议簇 &#xff08;1&a…

Highcharts的饼图大小的控制

在Highcharts中&#xff0c;饼图的大小是Highcharts自动计算并进行绘制。饼图的大小受数据标签大小、数据标签到切片的距离影响。当数据标签内容较多&#xff0c;并且距离切片较远时&#xff0c;饼图就会被压缩的很小。解决这个问题&#xff0c;有以下几种方法&#xff1a;&…

document.createDocumentFragment 以及创建节点速度比较

document.createDocumentFragment document.createDocumentFragment()方法创建一个新空白的DocumentFragment对象。 DocumentFragments是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段&#xff0c;将元素附加到文档片段&#xff0c;然后将文档片段附加到DOM树。…

Javascript重温OOP之原型与原型链

prototype原型对象 每个函数都有一个默认的prototype属性&#xff0c;其实际上还是一个对象&#xff0c;如果被用在继承中&#xff0c;姑且叫做原型对象。 在构造函数中的prototype中定义的属性和方法&#xff0c;会被创建的对象所继承下来。举个栗子&#xff1a; function F()…

webpack超详细配置

在这里就不详细介绍webpack来源以及作用了, 本篇博文面向新手主要说明如何配置webpack, 以及webpack的使用方法, 直到创建出一个合理的属于自己webpack项目; 流程 webpack安装 Step 1: 首先安装Node.js, 可以去Node.js官网下载.Step2: 在Git或者cmd中输入下面这段代码, 通过全局…