node 笔记5
数据库概述:
- 数据库就是存储数据的仓库,可以对数据进行分类存储,并提供强大的操作数据的方法,是一个独立的软件
- 常用的数据库有:mysql、mongodb、orcle。。。
- mongodb是我们前端上手最快的数据库,我们先学习数据库相关的概念,日后再学习其他数据库时就会很轻松
数据库概念:
- 数据库(database):一个数据库软件中可以创建多个数据库,每个数据库都是独立的存储数据的仓库
- 集合(collection):集合是某个数据库中的一类数据的集合(可以理解为JS中的数组)[ {}, {}, {}, {} ]
- 文档(document):是集合中一条具体的数据(可以理解为数组中的对象){ name: ‘zs’, age: 18 }
- 字段(field):是文档中具体的某个属性(可以理解为数组中的对象的某个键值对)name: ‘zs’
使用nodejs连接数据:
-
启动数据库:打开命令行,执行:
net start mongodb
、mongod
(Mac) -
停止数据库:打开命令行,执行:
net stop mongodb
、mongod
(Mac) -
使用第三方模块mongoose去操作数据库,范例:
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/dbname').then(() => { console.log('数据库连接成功') }).catch(err => { console.log('数据库连接失败:', err) })
补充说明:如果你连接的数据库不存在,mongodb会在第一次插入数据的时候自动给我们创建
创建集合及插入文档:
-
创建集合,分为两步:
- 创建集合规则
- 应用集合规则,创建集合
-
创建文档,分为两步:
new 集合()
创建文档实例- 调用save方法保存
-
范例:
const mongoose = require('mongoose') mongoose .connect('mongodb://localhost:27017/test01') .then(() => { console.log('数据库连接成功') }) .catch(err => { console.log(err) }) const userSchema = new mongoose.Schema( { name: String, age: Number, isMarry: Boolean }, { versionKey: false } ) const User = mongoose.model( 'User' /* 是JS在运行时,内存中的集合名称,可以和数据库中真正的集合名称不一致,但是一般都是保持一致的 */, userSchema, 'User' /* 指定数据库里的集合名称,如果不指定,默认会改成小写的复数形式 */ ) const ls = new User({ name: 'ls', age: 18, isMarry: false }) ls.save()
-
插入文件的另一种方式:可以使用集合构造函数的create方法来插入文档(推荐用这个),范例:
// [ 回调函数形式 User.create({ name: 'ww', age: 19, isMarry: true }, (err, user) => { cnosole.log(user) }) // ] 回调函数形式 // [ Promise 形式 User.create({ name: 'ww', age: 19, isMarry: true }).then(doc => { console.log(doc) }) // ] Promise 形式 // [ async await 形式 (推荐) ;(async () => { const ww = await User.create({ name: 'zl', age: 59, isMarry: true }) console.log(ww) })() // ] async await 形式
如果你写代码时,不喜欢加分号,那么在自执行函数前面是需要加分号的
向数据库中导入数据:
- 导入数据:
mongoimport -d 数据库名称 -c 集合名称 --file 要导入的文件路径
- 注意:mongodb安装目录的bin目录下存放的是mongodb相关的可执行文件,需要加入到path系统环境变量中,才阔以在命令行中执行命令
查询文档:
-
find():查找多个,返回的是数组,不管有多少个,返回的都是数组
-
findOne():查找一个,返回的是一个文档,如果匹配到多条,返回第一条
-
共同点:它们都返回Promise对象,既然返回的是Promise对象,那么就推荐使用async/await关键字去调用,都可以带查询条件
-
大于、小于:
User.find({ age: { $gt: 18, $lt: 40 } }).then(users => console.log(users))
-
包含:
User.find({ hobbies: { $in: ['敲代码'] } }).then(users => console.log(users))
-
筛选字段(_id会默认带上,如果不要在前面加个-):
User.find().select('name age').then(users => console.log(users))
-
排序:
// 升序 User.find().sort('age').then(users => console.log(users)) // 降序 User.find().sort('-age').then(users => console.log(users))
-
分页,跳过n条(skip),查n条(limit)
// 获取第4页的数据 User.find().skip(3 * 10).limit(10).then(users => console.log(users))
删除文档:
-
删除单个:
User.findOneAndDelete({ 条件 }).then...
- 返回的是被删除的文档
- 如果匹配到多条,删除第一条
-
删除多个:
User.deleteMany({ 一定不要忘记带条件,如果不带就是无条件删除该集合中所有数据 }).then...
- 返回值是本次删除操作的信息对象,形如:
{ n: 2, ok: 1, deletedCount: 2 }
- n:表示匹配的条数
- ok:表示本次删除操作是否执行成功,1:成功,0:失败
- deletedCount:代表已经被删除的条数
- 补充说明:当本次删除操作异常时,n和deletedCount就有可能不一致
- 返回值是本次删除操作的信息对象,形如:
更新文档:
-
更新单个:
User.updateOne({ 条件 }, { 要更新的值 }).then...
- 返回值是更新信息对象,形如:
{ n: 1, nModified: 1, ok: 1 }
- n:表示匹配的条数
- nModified:表示已经更新的条数
- ok:表示本次更新操作是否执行成功,1:成功,0:失败
- 返回值是更新信息对象,形如:
-
更新多个:
User.updateMany({ 条件 }, { 要更新的值 }).then...
- 返回值和updateOne一样
给数据账号密码权限:
第一种方法:
- mongo
- use admin
- db.auth(‘root’, ‘root’)
- user 数据库名
- db.createUser({ user: ‘账号’, pwd: ‘密码’,roles:[‘readWrite’] })
- exit
第二种方法:
- mongo -u root -p root
- 同上
mongoose验证:
-
在创建集合规则的时候,可以设置当前字段的验证规则,验证失败就不允许插入
-
必填:required
-
字符串最小长度:minlength
-
字符串最大长度:maxlength
-
去除字符串两边的空格:trim
-
可以用数组的形式的第二个参数指定错误消息,如:
new mongoose.Schema({ name: String, age: Number, stuNo: { type: String, required: true, minlength: [2, '学号太短了'] } })
-
最小值:min
-
最大值:max
-
默认值:default
-
枚举值:enum,规定了可选值,只能从规定的这几个值里面选择
-
自定义规则:validate,范例:
new mongoose.Schema({ age: { type: Number, validate: { // 验证器,验证函数,如果想让这个验证通过,那么返回true,否则返回false validator: (v) => { // 这个v就是实际要验证的值 return v >= 18 && v <= 100 }, // 错误消息 message: '您的年龄填写错误' } } })
-
捕获mongoose错误消息:
User.create({ ... })
.then(...)
// 所有验证错误的字段信息都是以键值对的形式存储在错误对象中
.catch({ errors } => {
for (let key in errors) {
const { message } = errors[key]
console.log(message) // 错误消息
}
})
集合关联:
-
使用唯一标识id对集合进行关联,类型是:
mongoose.Schema.Types.ObjectId
,需要添加ref: 集合名称
属性- 注意:这个ref属性的集合名称是以内存中的集合名称为准,并不是数据库中的集合名称
-
可以使用
poppulate
方法来对集合关联查询 -
范例:
const mongoose = require('mongoose') ;(async () => { // 集合规则和集合一起创建的 const User = mongoose.model('User', { name: String }, 'User') // 集合规则和集合一起创建的 const Article = mongoose.model('Article', { title: String, author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } }, 'Article') const articleArr = await Article.find().populate('author') console.log(articleArr) })()