一皮服、數(shù)據(jù)庫概述及環(huán)境搭建
1.1 為什么要使用數(shù)據(jù)庫
- 動態(tài)網(wǎng)站中的數(shù)據(jù)都是存儲在數(shù)據(jù)庫中的
- 數(shù)據(jù)庫可以用來持久存儲客戶端通過表單收集的用戶信息
- 數(shù)據(jù)庫軟件本身可以對數(shù)據(jù)進行高效的管理良蛮,以便我們可以快速的查找數(shù)據(jù)
1.2 什么是數(shù)據(jù)庫
數(shù)據(jù)庫即存儲數(shù)據(jù)的倉庫,可以將數(shù)據(jù)進行有序的分門別類的存儲屠阻。它是獨立于語言之外的軟件,可以通過API去操作它国章。
常見的數(shù)據(jù)庫軟件有:mysql侦副、mongoDB、oracle剖踊。
1.3 下載MongoDB 和MongoDB Compass
可視化軟件
MongoDB可視化操作軟件庶弃,是使用圖形界面操作數(shù)據(jù)庫的一種方式。
1.4 數(shù)據(jù)庫相關(guān)概念
在一個數(shù)據(jù)庫軟件中可以包含多個數(shù)據(jù)倉庫德澈,在每個數(shù)據(jù)倉庫中可以包含多個數(shù)據(jù)集合歇攻,每個數(shù)據(jù)集合中可以包含多條文檔(具體的數(shù)據(jù))。
術(shù)語
database
:數(shù)據(jù)庫梆造,mongoDB數(shù)據(jù)庫軟件中可以建立多個數(shù)據(jù)庫
collection
:集合缴守,為了區(qū)分不同類別的數(shù)據(jù),在一個數(shù)據(jù)庫下面分成一組組數(shù)據(jù)的集合(比如商品集合镇辉、用戶信息集合)屡穗。一個數(shù)據(jù)庫中可以有好多個集合。
document
:文檔忽肛,一個集合里所有數(shù)據(jù)的具體展現(xiàn)鸡捐。JSON對象,可以理解為JavaScript中的對象
field
:字段麻裁,文檔中的屬性名稱,可以理解為JavaScript中的對象屬性
1.5 Mongoose第三方包
使用Node.js操作MongoDB數(shù)據(jù)庫需要依賴Node.js第三方包mongoose
使用npm install mongoose
命令下載
1.6 啟動MongoDB
Windows在命令行工具中運行net start mongoDB
即可啟動MongoDB,否則MongoDB將無法連接煎源。關(guān)閉語句是net stop mongoDB
MacOs下:
安裝:
- 將MongoDB Community Server最新版macOS版壓縮包色迂,并解壓在/usr/local/目錄下,并把這個文件夾重命名為mongodb
- 把mongodb的可執(zhí)行文件全部復(fù)制到/usr/local/bin/目錄下
sudo cp /usr/local/mongodb/bin/* /usr/local/bin/
再創(chuàng)建指向PATH變量目錄的二進制文件的軟鏈接(官方直譯)
sudo ln -s /usr/local/mongodb/bin/* /usr/local/bin/
運行:
- 創(chuàng)建數(shù)據(jù)庫存放目錄
sudo mkdir -p /usr/local/var/mongodb
再創(chuàng)建日志目錄
sudo mkdir -p /usr/local/var/log/mongodb
- 給用戶開放寫入權(quán)限
sudo chown 你的用戶名 /usr/local/var/mongodb
sudo chown 你的用戶名r /usr/local/var/log/mongodb
- 運行方式一:加上數(shù)據(jù)庫目錄和日志目錄參數(shù)
mongod --dbpath /usr/local/var/mongodb --logpath /usr/local/var/log/mongodb/mongo.log --fork
另外可以把這個命令太長可以取別名
(1)沒有配置文件的時候新建touch .bash_profile
手销,
(2)然后open .bash_profile
歇僧,在里面寫上alias mongostart='mongod --dbpath /usr/local/var/mongodb --logpath /usr/local/var/log/mongodb/mongo.log --fork'
保存
(3)使配置生效source .bash_profile
(4)以后使用mongostart
就可以啟動mongodb了 - 運行方式二:執(zhí)行配置文件
mongod --config /usr/local/etc/mongod.conf
這個mongod.conf配置文件因為不是用brew安裝的,需要自己新建锋拖,我加的配置內(nèi)容如下诈悍,具體參數(shù)可以詳見https://docs.mongodb.com/manual/reference/configuration-options/
# systemLog Options
systemLog:
destination: file
path: "/usr/local/var/log/mongodb/mongod.log"
logAppend: true
quiet: true
# storage Options
storage:
dbPath: "/usr/local/var/mongodb"
journal:
enabled: true
processManagement:
fork: true
# net Options
net:
bindIp: 127.0.0.1
port: 27017
# setParameter Option
setParameter:
enableLocalhostAuthBypass: false
確認(rèn)mongodb是否成功運行:
ps aux | grep -v grep | grep mongod
關(guān)閉mongodb:
先在命令行輸入mongo
使用 mongo shell
然后
use admin
db.shutdownServer()
1.7 數(shù)據(jù)庫連接
使用mongoose提供的connect方法即可連接數(shù)據(jù)庫。
mongoose.connect('mongodb://localhost/數(shù)據(jù)庫名稱',{useNewUrlParser:true})
.then(() => console.log('數(shù)據(jù)庫連接成功'))
.catch(err => console.log('數(shù)據(jù)庫連接失敗', err));
1.8 創(chuàng)建數(shù)據(jù)庫
在MongoDB中不需要顯式創(chuàng)建數(shù)據(jù)庫兽埃,如果正在使用的數(shù)據(jù)庫不存在侥钳,MongoDB會自動創(chuàng)建。
二柄错、MongoDB增刪改查操作
2.1 創(chuàng)建集合
創(chuàng)建集合分為兩步舷夺,一是對集合設(shè)定規(guī)則,二是創(chuàng)建集合售貌,創(chuàng)建mongoose.Schema
構(gòu)造函數(shù)的實例即可創(chuàng)建集合给猾。
mongoose.model
方法創(chuàng)建集合,集合的名稱必須大寫
// 設(shè)定集合規(guī)則
const courseSchema = new mongoose.Schema({
name: String,
author: String,
isPublished: Boolean
});
// 創(chuàng)建集合并應(yīng)用規(guī)則
const Course = mongoose.model('Course', courseSchema); // courses
2.2 創(chuàng)建文檔
創(chuàng)建文檔實際上就是向集合中插入數(shù)據(jù)颂跨。
分為兩步:
- 創(chuàng)建集合實例敢伸。
- 調(diào)用實例對象下的save方法將數(shù)據(jù)保存到數(shù)據(jù)庫中。恒削、
方式一:創(chuàng)建集合實例
// 創(chuàng)建集合實例
const course = new Course({
name: 'Node.js course',
author: '黑馬講師',
tags: ['node', 'backend'],
isPublished: true
});
// 將數(shù)據(jù)保存到數(shù)據(jù)庫中
course.save();
方式二:create方法加回調(diào)函數(shù)方式
Course.create({name: 'JavaScript基礎(chǔ)', author: '黑馬講師', isPublish: true}, (err, doc) => {
// 錯誤對象
console.log(err)
// 當(dāng)前插入的文檔
console.log(doc)
});
方式二:create方法返回的是Promise對象池颈,用Promise實例執(zhí)行異步函數(shù)
Course.create({name: 'JavaScript基礎(chǔ)', author: '黑馬講師', isPublish: true})
.then(doc => console.log(doc))
.catch(err => console.log(err))
2.3 mongoDB數(shù)據(jù)庫導(dǎo)入數(shù)據(jù)
mongoimport –d 數(shù)據(jù)庫名稱 –c 集合名稱 要導(dǎo)入的數(shù)據(jù)文件路徑
注意,如果集合名稱已存在蔓同,會覆蓋該集合原本的數(shù)據(jù)饶辙。
2.4 查詢文檔
1. find方法,返回符合條件的集合(數(shù)組)(條件為空則查找所有文檔)
集合.find().then(result => console.log(result))
User.find({_id: '5c09f267aeb04b22f8460968'}).then(result => console.log(result))
// 返回文檔集合
[{
_id: 5c0917ed37ec9b03c07cf95f,
name: 'node.js基礎(chǔ)',
author: '黑馬講師‘
},{
_id: 5c09dea28acfb814980ff827,
name: 'Javascript',
author: '黑馬講師‘
}]
2. findOne方法斑粱,返回符合條件的第一個對象
根據(jù)條件查找文檔
Course.findOne({name: 'node.js基礎(chǔ)'}).then(result => console.log(result))
// 返回文檔
{
_id: 5c0917ed37ec9b03c07cf95f,
name: 'node.js基礎(chǔ)',
author: '黑馬講師‘
}
3. 匹配范圍弃揽,大于
lt
User.find({age: {$gt: 20, $lt: 50}}).then(result => console.log(result))
4. 匹配包含 $in,應(yīng)用:關(guān)鍵字查詢
User.find({hobbies: {$in: ['敲代碼']}}).then(result => console.log(result))
5. 選擇要查詢的字段
User.find().select('name email').then(result => console.log(result))
主鍵id會默認(rèn)輸出则北,select('name email -_id')
就可以只輸出想要的字段
6. 排序
// 將數(shù)據(jù)按照年齡進行排序
User.find().sort('age').then(result => console.log(result))
默認(rèn)升序矿微,降序排列改成sort('-age')
即可
7. skip 跳過多少條數(shù)據(jù) limit 限制查詢數(shù)量,應(yīng)用:分頁功能
User.find().skip(2).limit(2).then(result => console.log(result))
2.5 刪除文檔
刪除單個尚揣,返回Promise對象涌矢,即被刪除的那條文檔。如果匹配到多條快骗,會刪除匹配的第一條
Course.findOneAndDelete({_id: '5c09f267aeb04b22f8460968'}).then(result => console.log(result))
刪除多個娜庇,返回值是{n:條數(shù),ok:1}
User.deleteMany({}).then(result => console.log(result))
2.6 更新文檔
更新單個塔次,返回的是{ n: 1, nModified: 1, ok: 1 }
User.updateOne({查詢條件}, {要修改的值}).then(result => console.log(result))
User.updateOne({name: '李四'}, {age: 120, name: '李狗蛋'}).then(result => console.log(result))
更新多個,批量修改名秀,返回{ n: 6, nModified: 6, ok: 1 }
User.updateMany({查詢條件}, {要更改的值}).then(result => console.log(result))
User.updateMany({}, {age: 300}).then(result => console.log(result))
2.7 mongoose驗證
在創(chuàng)建集合規(guī)則時励负,可以設(shè)置當(dāng)前字段的驗證規(guī)則,驗證失敗就則輸入插入失敗匕得。
required: true
必傳字段
minlength:3
字符串最小長度
maxlength: 20
字符串最大長度
min: 2
數(shù)值最小為2
max: 100
數(shù)值最大為100
enum: ['html', 'css', 'javascript', 'node.js']
trim: true
去除字符串兩邊的空格
validate
: 自定義驗證器
default: 默認(rèn)值
獲取錯誤信息:error.errors['字段名稱'].message
2.8 集合關(guān)聯(lián)
通常不同集合的數(shù)據(jù)之間是有關(guān)系的继榆,例如文章信息和用戶信息存儲在不同集合中,但文章是某個用戶發(fā)表的汁掠,要查詢文章的所有信息包括發(fā)表用戶略吨,就需要用到集合關(guān)聯(lián)。
- 使用id對集合進行關(guān)聯(lián)
-
使用populate方法進行關(guān)聯(lián)集合查詢
// 用戶集合
const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } }));
// 文章集合
const Post = mongoose.model('Post', new mongoose.Schema({
title: { type: String },
// 使用ID將文章集合和作者集合進行關(guān)聯(lián)
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}));
//聯(lián)合查詢
Post.find()
.populate('author')
.then((err, result) => console.log(result));
2.9 案例:用戶信息增刪改查
搭建網(wǎng)站服務(wù)器考阱,實現(xiàn)客戶端與服務(wù)器端的通信
連接數(shù)據(jù)庫翠忠,創(chuàng)建用戶集合,向集合中插入文檔
當(dāng)用戶訪問/list時羔砾,將所有用戶信息查詢出來
將用戶信息和表格HTML進行拼接并將拼接結(jié)果響應(yīng)回客戶端
當(dāng)用戶訪問/add時负间,呈現(xiàn)表單頁面,并實現(xiàn)添加用戶信息功能
當(dāng)用戶訪問/modify時姜凄,呈現(xiàn)修改頁面政溃,并實現(xiàn)修改用戶信息功能
當(dāng)用戶訪問/delete時,實現(xiàn)用戶刪除功能