1.数据库概述及环境搭建
1.1 为什么要使用数据库
- 动态网站中的数据都是存储在数据库中的
- 数据库可以用来持久存储客户端通过表单收集的用户信息
- 数据库软件本身可以对数据进行高效的管理
1.2 什么是数据库
数据库是用于存储数据的仓库,可以将数据进行有序的分门别类的存储。它是独立于语言之外的软件,可以通过API去操作它。
常见的数据库软件有:mysql、mongoDB、oracle。
1.3 MongoDB数据库下载安装
下载地址:MongoDB 数据库下载地址
选择适合自己电脑的版本,然后点击douwnload下载,我是复制下载链接用IDM下载的,速度还挺快的
顺便在这里把MongoDB可视化软件compass下载了
同样选择合适的版本download
安装的时候,如果版本下载正确,顺利的话一直next就好了,最后面的时候,如果你已经提前下载好可视化软件,这里要把勾勾去掉,否则它会自动去帮你下载compass软件
安装好后,直接运行compass可视化软件,等待一会软件自己安装完成
安装好后如下图,学习用,这里数据不用做任何修改
一开始我是自己去官网下载的安装包,安装出错,查了电脑版本信息,感觉自己没有选错版本,不知道为啥一运行就报错,错误信息:安装MongoDB 提示is only support on windown 10 or windowns 2016 later,懵!
我的电脑信息如下图:
后来用黑马提供的安装包就没问题,如果有大佬知道原由还望提点一下,谢谢啦~
1.4 Mongoose第三方包
- 使用Node.js操作MongoDB数据库需要依赖Node.js第三方包mongoose
- 使用npm install mongoose命令下载
npm install mongoose
1.5 启动MongoDB和连接数据库
选择管理员身份运行PowerShell,在命令行工具中运行net start mongodb即可启动MongoDB,否则MongoDB将无法连接。
net start mongodba 启动服务
net start mongodb
net stop mongodb 停止服务
net stop mongodb
使用mongoose提供的connect方法即可连接数据库。
文件名称01test.js,代码如下:
数据库名称为playground
//引入mongoose第三方模块,用于操作数据库
const mongoose = require('mongoose');
//创建连接
mongoose.connect('mongodb://localhost/playground')
.then(() => {
console.log('数据库链接成功');
})
.catch(err => {
console.log(err,'数据库链接失败');
});
注意:在MongoDB中不需要显式创建数据库,如果正在使用的数据库不存在,MongoDB会自动创建。
用node 01test.js命令运行后,虽然提示连接成功,但是还有其他信息
大概意思说:(节点:16396)DeprecationWarning:当前的URL字符串分析器已弃用,将在将来的版本中删除。要使用新的解析器,请将选项{useNewUrlParser:true}传递给MongoClient.connect连接.
(节点:16396)DeprecationWarning:当前服务器发现和监视引擎已弃用,将在将来的版本中删除。要使用新的服务器发现和监视引擎,请将选项{useUnifiedTopology:true}传递给MongoClient构造函数。
按照提示改一下代码再运行就OK了
//引入mongoose第三方模块,用于操作数据库
const mongoose = require('mongoose');
//connect方法创建连接
mongoose.connect('mongodb://localhost/playground',{useUnifiedTopology: true, useNewUrlParser: true })
.then(() => {
console.log('数据库链接成功');
})
.catch(err => {
console.log(err,'数据库链接失败');
});
2. MongoDB增删改查操作
2.1 创建集合
创建集合分为两步,一是对对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合。
集合规则:我理解为创建表的列(字段),说明每一列的名称和数据类型
集合:就相当于SQL数据库的表
// Schema设定集合规则
const courseSchema = new mongoose.Schema({
name: String,
author: String,
isPublished: Boolean
});
// model方法创建集合并应用规则,生成构造函数
//第一个参数:Course为集合名称,第二个参数:courseSchema使用的集合规则
const Course = mongoose.model('Course', courseSchema); // courses
注意:集合名称首字母一定要大写
2.2 创建文档
创建文档实际上就是向集合中插入数据,也就是相当于往表中插入数据。
方法一:
① 创建集合实例。
② 调用实例对象下的save方法将数据保存到数据库中。
// 创建集合实例
new Course({
name:'mongoose 教程',
author:'黑马讲师',
isPublish:true
})
//将集合(表)插入到数据库中
.save();
保存文件运行,再到compass视图软件,可以发现已经成功插入一条数据了
方法二
create方法,集合构造函数下有一个create方法,用于向集合中插入文档
//1.第一个参数为要插入的对象,第二个参数为回调函数
Course.create({name: 'JavaScript基础', author: '黑马讲师', isPublish: true}, (err, doc) => {
// 错误对象
console.log(err)
// 当前插入的文档
console.log(doc)
});
这里有回调函数,说明当前的API为异步API。这里MongoDB数据库的所有操作都是异步操作,所以上述代码我们还可以改成promise形式,返回结果为promise对象。
Course.create({name: 'JavaScript基础', author: '黑马讲师', isPublish: true})
.then(doc => console.log(doc))
.catch(err => console.log(err));
如果对promise记忆模糊,可以看我的http那一篇博文
2.3 mongoDB数据库导入数据
首先配置环境变量:找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中。
复制路径,放到系统变量中,跟配置JAVA环境变量一样
配置好后,需要重启PowerShell
准备要导入的文件,我这里用黑马提供的user.json文件,把它copy到目标目录下
mongoimport命令格式:mongoimport –d 数据库名称 –c 集合名称 –file 要导入的数据文件
按照mongoimport命令格式输入完整的命令
mongoimport -d playground -c users --file ./user.json
到compass软件查看一下结果
2.4 查询文档
查找所有数据
//集合规则
const userSchema = mongoose.Schema({
name:String ,
age:Number,
hobbies:[String],
email:String,
password:String
});
//使用集合规则创建集合
const Users = mongoose.model('Users',userSchema);
//用集合下的find()方法查询数据并打印在控制台
//前面提到过mongodb的所有操作均是异步操作
//所以这个find也属于异步函数,其返回结果为promise类型,可以用then来接收返回成功的结果
//根据条件查找文档(条件为空则查找所有文档)
Users.find().then(res => console.log(res));
这个find()函数里面是可以接收参数进行查找的
Users.find({_id:'5c09f1e5aeb04b22f8460965'}).then(res => console.log(res));
返回结果可以看到跟对应的数据一毛一样
用find()方法,不管返回数据单条还是多条,均以数组形式返回,如果想返回的数据为对象形式,我们可以使用findOne()方法,这个方法查找的数据如果有多条结果,默认返回当前集合中符合条件的第一条数据。
Users.findOne({password:'123456'}).then(res => console.log(res));
返回结果
// 匹配大于($gt):n 小于($lt):m
Users.find({age: {$gt: 20, $lt: 50}}).then(result => console.log(result));
// 匹配包含($in):['要匹配的内容']
Users.find({hobbies: {$in: ['吃饭']}}).then(result => console.log(result));
//选择要查询的字段 select('字段以空格形式隔开')
//默认字段_id会被查询出来,如果不想查询结果出现某个字段,在那个字段名称前加上-
Users.find().select('name email -_id').then(result => console.log(result));
// 将数据按照年龄进行排序 sort('以哪个字段排序')
Users.find().sort('age').then(result => console.log(result));
//默认升序,如果想降序排列,在字段前面加上-
Users.find().sort('-age').then(result => console.log(result));
// skip 跳过多少条数据 skip(n) limit 限制查询数量 limit(n)
Users.find().skip(2).limit(2).then(result => console.log(result))
2.5添加文档
//插入多条数据
Course.insertMany([{
name:'mongoose 教程',
author:'黑马讲师',
isPublish:true
},{
name:'http 教程',
author:'黑马讲师',
isPublish:true
},{
name:'js 教程',
author:'黑马讲师',
isPublish:true
},{
name:'mongoose 教程',
author:'讲师',
isPublish:true
},{
name:'http 教程',
author:'讲师',
isPublish:true
}]);
2.6 删除文档
// 删除单个,删除一个匹配文档 findOneAndDelete({})可带或不带参数
Course.findOneAndDelete().then(result => console.log(result));
// 删除多个 deleteMany({})可带或不带参数,具体情况具体分析
Course.deleteMany({author:'讲师'}).then(res => console.log(res));
2.7 更新文档
// 更新单个
//Users.updateOne({查询条件}, {要修改的值}).then(result => console.log(result));
Users.updateOne({name :'李四'},{age:18}).then(res => console.log(res));
// 更新多个
//Users.updateMany({查询条件}, {要更改的值}).then(result => console.log(result));
//查询条件参数为空,表明要修改所以的文档
Users.updateMany({},{age:80}).then(res => console.log(res));
2.8 mongoose验证
在创建集合规则时,可以设置当前字段的验证规则,验证失败就则输入插入失败。
- required: true 必传字段
- minlength:3 字符串最小长度
- maxlength: 20 字符串最大长度
- min: 2数值最小为2
- max: 100 数值最大为100
- enum: [‘html’, ‘css’, ‘javascript’, ‘node.js’]
- trim: true 去除字符串两边的空格
- validate: 自定义验证器 default: 默认值
获取错误信息:error.errors[‘字段名称’].message
//集合规则
const postSchema = new mongoose.Schema({
title:{
type:String,
required:[true,'请传入文章标题'],
minlength:[2,'请输入长度大于2的标题'],
maxlength:[5,'请输入长度小于5的标题'],
trim:true
},
age: {
type:Number,
min:[18,'年龄不能小于18岁'],
max:[60,'年龄不能大于60岁']
},
publishDate: {
type:Date,
//默认值
default:Date.now
},
category: {
type:String,
//enum为可选值
enum:{
values:['html','css'],
message:'请输入正确的目录名称'
}
},
author: {
type:String,
//自定义验证
validate : {
validator: v => {
//v 传入的值,将要验证的
//返回布尔值
//返回true 验证成功
//返回false 验证失败
return v && v.length > 4;
},
//自定义错误信息
message:'作者名字输入有误'
}
}
});
//创建集合
const Post = mongoose.model('Post',postSchema);
//传入数据
Post.create({title:'ab',age:65,category:'jvav',author:'au'})
.then(res => console.log(res))
.catch(error => {
//获取错误信息对象
const err = error.errors;
//循环错误信息对象
for(var attr in err){
console.log(err[attr]['message']);
}
});
2.9 集合关联
通常不同集合的数据之间是有关系的,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联。
- 使用id对集合进行关联
- 使用populate方法进行关联集合查询
// 文章集合规则
const postSchema = new mongoose.Schema({
title: {
type: String
},
// 使用ID将文章集合和作者集合进行关联
author: {
type:mongoose.Schema.Types.ObjectId,
//前提已经存在一个users表,没有的话需要创建
ref:'User'
}
});
// 文章集合
const Post = mongoose.model('Post', postSchema);
//创建文章
//author:'5eca3f5e90abecad8830c179' 使用users集合中对应的id进行关联
Post.create({title:'Mongoose is very good!',author:'5eca3f5e90abecad8830c179'}).then(res => console.log(res));
//联合查询
Post.find().populate('author').then(res => console.log(res));