一、cmd終端常用命令
1、dir ?????????顯示目錄里面的所有文件(包括文件夾和文件)
2、cd.. ????????回到上一級目錄
3、cd\ ?????????回到根目錄
4、cd 路徑 ?????跳轉(zhuǎn)到指定的目錄(路徑可以是絕對路徑,也可以是相對路徑)
相對路徑是相當(dāng)于當(dāng)前路徑的路徑;絕對路徑是相對于當(dāng)前盤符根路徑的路徑。
5、盤符名稱: ???切換盤符(比如:d:,回車后就會切換到d盤)
6、cls ?????????清屏(清空屏幕)
7、md 目錄名稱 ?創(chuàng)建目錄
8、rd 目錄名稱 ?刪除空目錄
9、del 文件名 ??刪除指定的文件
10、del 目錄名 ?刪除目錄里面的全部文件
11、copy 命令用于復(fù)制文件
12、move 命令用于移動文件
打開當(dāng)前目錄里面的文件或程序:文件名.擴(kuò)展名 回車
我們在cmd窗口中,輸入文件名.擴(kuò)展名 回車,首先它會在當(dāng)前目錄中找該文件是否存在,存在則打開該文件。如果當(dāng)前目錄中沒有這個文件,就會到系統(tǒng)變量的path中,遍歷所有的路徑,找這個文件是否存在,存在則打開文件;如果還是沒有,則報錯。
二、模塊
js程序不能直接運(yùn)行,必須要在瀏覽器中運(yùn)行;在網(wǎng)頁中引入js程序時,一定要注意引入的順序,因為前后js可能是有關(guān)系的。綜上,引入nodejs解決問題。
在nodejs環(huán)境中,每一個獨(dú)立的js文件,就是一個獨(dú)立模塊。
每個獨(dú)立的模塊是一個私有的作用域,每一個獨(dú)立模塊其實(shí)就是獨(dú)立方法。這個方法,提供了5個參數(shù):exports, require, module, __filename, __dirname。
1、exports對象
nodejs中,導(dǎo)出當(dāng)前模塊的成員,可以用exports,也可以用module.exports。其實(shí)exports對象,指向了module.exports對象,最終導(dǎo)出的是module.exports對象。
通常情況下exports
(1)使用exports對象導(dǎo)出
exports導(dǎo)出成員時,不能重新給exports賦值一個新對象,只能一個一個導(dǎo)出。
let?money =?10000
let?city =?'南京'
exports.money =?money
exports.city =?city
注意:不能采用下面的方式導(dǎo)出成員
?exports?=?{
? ? money:money,
? ? city:city
}
(2)使用module.exports
module.exports導(dǎo)出成員時,既可以一個一個導(dǎo)出,也可以通過賦值一個對象的方式導(dǎo)出。
module.exports.fun1?=?fun1
module.exports?=?{
? ? money:money,
? ? city:city,
? ? fun1:fun1
}
2、require方法
用于導(dǎo)入其他模塊里面的成員。
在nodejs中,通過require方法,導(dǎo)入其他模塊。一般情況下,我們會通過解構(gòu)賦值的方式,直接從導(dǎo)入的對象中獲取需要的成員。
let?{money,city,fun1} =?require('./index03.js')
3、module對象
是當(dāng)前模塊本身,它里面的exports對象屬性,也是用于導(dǎo)出當(dāng)前模塊里面的成員。
4、__filename變量
返回當(dāng)前模塊文件的絕對路徑。
console.log(__filename);// E:\kw\kwstudy\nodeJS\L01\index03.js
5、__dirname變量
返回當(dāng)前模塊文件所在目錄的絕對路徑。
console.log(__dirname);// E:\kw\kwstudy\nodeJS\L01
三、通過require導(dǎo)入模塊
1、require()
require方法,用于導(dǎo)入模塊,方法的參數(shù)是:模塊的標(biāo)識。
導(dǎo)入模塊時,模塊標(biāo)識如果沒有文件的后綴名,
(1)首先判斷該模塊是不是系統(tǒng)模塊
(2)如果不是系統(tǒng)模塊,再判斷是不是第三方模塊
(3)如果導(dǎo)入的是自定義包里面的模塊,可以省略包里面的具體的文件
// 表示導(dǎo)入自定義math包里的模塊,默認(rèn)是math包里的index.js文件
let?math?=?require('./math')??
2、系統(tǒng)模塊
通過系統(tǒng)模塊的名稱導(dǎo)入。
let?path?=?require('path')
3、第三方模塊
通過模塊的名稱導(dǎo)入(這個名稱是package.json文件中name屬性對應(yīng)的名稱)。
let?math?=?require('math')
4、自定義模塊
通過模塊的路徑導(dǎo)入,路徑可以是相對路徑,也可以是絕對路徑。
四、global
在node環(huán)境中,沒有window對象。有一個全局對象global,類似于瀏覽器環(huán)境中的window對象。
五、npm
(1)下載包
備注:install的簡寫是i,--save的簡寫是-S,--save-dev的簡寫是-D,--global的簡寫-g。
npm install 包名 ??????????????下載包 (默認(rèn)會將下載的包添加到生產(chǎn)環(huán)境依賴,生產(chǎn)環(huán)境依賴的包參與本項目的打包)
npm install 包名 --save ???????(--save表示下載包,并添加到生產(chǎn)環(huán)境依賴)
npm install 包名 --save-dev ???(--save-dev表示下載包,并添加到開發(fā)環(huán)境依賴,只是開發(fā)時依賴該包,不參與本項目的打包)
npm install 包名 --global ?????安裝全局插件
使用npm下載第三方包后,會在項目根路徑中添加一個package-lock.json文件。該文件是可以刪除的,它的作用是記錄第三方包的完整信息,方便下次下載包時快速定位該包的信息,省去了查找包的時間。
(2)升級包
npm update 包名 ???????????????對指定包進(jìn)行升級
npm update ????????????????????升級所有包
[if !supportLists](1)[endif]刪除包
備注:remove的簡寫是r
npm remove 包名 ???????????????移除包
npm uninstall 包名 ????????????卸載包(功能等同于移除包)
(4)下載所有依賴包
npm install/i ????????根據(jù)package.json文件中的依賴關(guān)系,下載當(dāng)前項目所依賴的包
3、npm鏡像地址
(1)查看npm鏡像地址
npm config get registry
(2)修改npm鏡像地址
① npm config edit 打開npm的配置文件,然后修改
registry=http://registry.npm.taobao.org/
② npm config set registry http://registry.npm.taobao.org
(3)還原npm原來的鏡像地址
npm config set registry https://registry.npmjs.org/
4、安裝cnpm中國npm鏡像客戶端
npm install cnpm -g ???全局安裝cnpm
cnpm的所有命令跟npm一樣。(唯一的區(qū)別是:cnpm install 包名,不會將下載的包默認(rèn)添加到生產(chǎn)環(huán)境依賴。必須要加上--save。)
5、安裝nodemon工具
nodemon是一種工具,可以自動監(jiān)測文件的變化,當(dāng)有變化時重新啟動服務(wù)。(需要使用nodemon時,先關(guān)閉自動保存)
npm i nodemon -g ?????全局安裝nodemon
nodemon ./index.js運(yùn)行index.js文件
六、yarn
1、安裝yarn包管理工具
npm install yarn -g
2、yarn鏡像地址
(1)查看yarn鏡像地址
yarn config get registry
(2)修改yarn鏡像地址
yarn config set registry http://registry.npm.taobao.org/
(3)還原yarn原理的鏡像地址
yarn config set registry http://registry.npmjs.org/
3、yarn的常用命令
(1)下載所有依賴包
yarn install === npm install ???????????????注意:npm中install,可以簡寫成i,yarn中不可以;但是yarn可以省略install。
(2)下載包
yarn add 包名 === npm install 包名 --save ???注意:--save可以省略,因為默認(rèn)就是添加到生產(chǎn)依賴。
yarn add 包名 --dev === npm install 包名 --save-dev
yarn global add 包名 === npm install 包名 --global ???注意:npm中--global可以簡寫成-g。
(3)刪除包
yarn remove 包名 === npm remove 包名 ????????注意:npm中remove,可以簡寫為r,yarn中不可以。
(4)升級包
yarn upgrade 包名 === npm update 包名
yarn upgrade === npm update
七、系統(tǒng)模塊path
1、定義
系統(tǒng)模塊path,用于操作路徑相關(guān)。
let?path?=?require('path')
2、join() 路徑拼接
path.join('路徑','路徑',...) ??該方法會根據(jù)當(dāng)前nodejs所在的系統(tǒng)環(huán)境,返回正確格式的拼接路徑。
不同的操作系統(tǒng),路徑的拼接符是不一樣的。windows系統(tǒng)中,路徑的拼接符是 / 或 \ ;linux系統(tǒng)中,路徑的拼接符是 / ;我們用nodeJS開發(fā)的程序,將來部署到什么操作系統(tǒng)的服務(wù)器上是不確定的。所以,使用join()方法,返回拼接路徑。
console.log(path.join('a','b','c','d'))// ?a\b\c\d
3、resolve()
帶參數(shù),path.resolve(相對路徑)方法,返回一個相對路徑的絕對路徑。
console.log(path.resolve('./file/a.txt'))?// ?E:\kw\kwstudy\nodeJS\1028\file\a.txt
不帶參數(shù),path.resolve()方法,返回當(dāng)前模塊所在目錄的絕對路徑。
console.log(path.resolve());// E:\kw\kwstudy\nodeJS\1028
全局變量__dirname,也是返回當(dāng)前模塊所在目錄的絕對路徑
console.log(__dirname);// E:\kw\kwstudy\nodeJS\1028
4、返回指定包(math)的絕對路徑
// E:\kw\kwstudy\nodeJS\1028\math
console.log(path.join(path.resolve(),'math'));
七、系統(tǒng)模塊path
1、定義
系統(tǒng)模塊path,用于操作路徑相關(guān)。
let?path?=?require('path')
2、join() 路徑拼接
path.join('路徑','路徑',...) ??該方法會根據(jù)當(dāng)前nodejs所在的系統(tǒng)環(huán)境,返回正確格式的拼接路徑。
不同的操作系統(tǒng),路徑的拼接符是不一樣的。windows系統(tǒng)中,路徑的拼接符是 / 或 \ ;linux系統(tǒng)中,路徑的拼接符是 / ;我們用nodeJS開發(fā)的程序,將來部署到什么操作系統(tǒng)的服務(wù)器上是不確定的。所以,使用join()方法,返回拼接路徑。
console.log(path.join('a','b','c','d'))// ?a\b\c\d
3、resolve()
帶參數(shù),path.resolve(相對路徑)方法,返回一個相對路徑的絕對路徑。
console.log(path.resolve('./file/a.txt'))?// ?E:\kw\kwstudy\nodeJS\1028\file\a.txt
不帶參數(shù),path.resolve()方法,返回當(dāng)前模塊所在目錄的絕對路徑。
console.log(path.resolve());// E:\kw\kwstudy\nodeJS\1028
全局變量__dirname,也是返回當(dāng)前模塊所在目錄的絕對路徑
console.log(__dirname);// E:\kw\kwstudy\nodeJS\1028
4、返回指定包(math)的絕對路徑
// E:\kw\kwstudy\nodeJS\1028\math
console.log(path.join(path.resolve(),'math'));
八、系統(tǒng)模塊fs
1、定義
系統(tǒng)模塊fs,用于操作文件相關(guān)。
let?fs?=?require('fs')
2、同步方式方式讀取文件
同步方式讀取文件,指的是文件的讀取過程必須是一個一個讀取。假如,后面還要讀取其他文件,必須要等到前面的文件讀取完成了,再讀取下一個文件。
(1)讀取文件 openSync/readSync/closeSync
① 打開文件,通過openSync方法打開文件,返回值是文件標(biāo)識(文件標(biāo)識是一個數(shù)字)
let?fd?=?fs.openSync('./file/a.txt','r')
② 讀取文件中的內(nèi)容,通過readSync方法讀取文件。
參數(shù)1:文件標(biāo)識
參數(shù)2:buffer容器
創(chuàng)建一個buffer容器,用于接收讀取到的數(shù)據(jù),其實(shí)就是開辟一段內(nèi)存空間(單位是字節(jié))。注意:一個漢字占用三個字節(jié)空間。
let?buf?=?Buffer.alloc(30)// 創(chuàng)建30字節(jié)的buffer容器
fs.readSync(fd,buf)// 用buf接收fd文件數(shù)據(jù)
③ 文件讀取結(jié)束后,需要關(guān)閉文件。
fs.closeSync(fd)// 關(guān)閉fd文件
[if !supportLists](2)[endif]一般方式讀取文件readFileSync()
fs.readFileSync(文件路徑)
let?buf?=?fs.readFileSync('./file/a.txt')
console.log('同步:'+buf.toString());
[if !supportLists]1、[endif]同步寫入文件
同步方式寫入文件的缺陷:如果要寫入多個文件,只能一個一個寫。
(1)寫入一個文件 openSync/writeSync/closeSync
① 打開文件,通過openSync方法打開文件,返回值是文件標(biāo)識(文件標(biāo)識是一個數(shù)字)
參數(shù)1:文件路徑,
參數(shù)2:打開文件的方式:r是讀,w是寫,a是追加。
let?fd?=?fs.openSync('./file/b.txt','a')
② 向文件中寫入內(nèi)容(如果需要寫入中文,加一個'utf-8';內(nèi)容是純英文可以省略)
fs.writeSync(fd,'HelloWorld你好','utf-8')
fs.writeSync(fd,'HelloWorld')
③ 文件寫入后,需要關(guān)閉文件
fs.closeSync(fd)
(2)一般方式寫入文件 writeFileSync()
writeFileSync()方法內(nèi)部已經(jīng)完成了文件的打開、讀取、關(guān)閉操作。
try{
? ? fs.writeFileSync('./file/a.txt','HelloWorld',{flag:'a'})// 追加參數(shù)a要寫在對象中
? ? console.log('同步:寫入成功!');
}catch{
? ? console.log('寫入失??!');
}
4、異步方式讀取文件
異步方式讀取文件,采用的都是回調(diào)函數(shù)的形式,相比較同步方式,代碼量變復(fù)雜了。優(yōu)勢是,可以同時操作多個文件。
(1)讀取文件 open/read/close
//01.打開文件
fs.open('./file/a.txt',(err,fd)=>{
?//回調(diào)函數(shù)的兩個參數(shù)分別是:錯誤信息,文件標(biāo)識,如果能夠打開文件,錯誤信息為null
if(!err){
?//02.讀取文件中的內(nèi)容
fs.read(fd,(err,num,buf)=>{
//回調(diào)函數(shù)的三個參數(shù)分別是:錯誤信息,讀取文件的字節(jié)數(shù),buffer內(nèi)容
if(!err){
console.log('讀取了'+num+'個字節(jié)');
console.log('內(nèi)容是:'+buf.toString());
? ? ? ? ? ? }
?//03.文件讀取結(jié)束后,需要關(guān)閉文件
fs.close(fd,(err)=>{
if(!err){
? ? ? ? ? ? ? ? ? ? console.log('文件讀取完畢!');
? ? ? ? ? ? ? ? }
? ? ? ? ? ? })
? ? ? ? })
? ? }
})
(2)一般方式讀取文件 readFile()
方法內(nèi)部,幫我們完成了文件的打開,讀取,關(guān)閉操作。
fs.readFile('./file/a.txt',(err,buf)=>{
if(!err){
console.log('異步:'+buf.toString());
? ? }
})
5、異步方式寫入文件
(1)寫入文件 open/read/close
// 01.打開文件
// 參數(shù)1:文件位置
// 參數(shù)2:打開文件的方式,r是讀,w是寫,a是追加
fs.open('./file/b.txt','a',(err,fd)=>{
if(!err){
?// 02.向文件中寫入內(nèi)容
fs.write(fd,'HelloWorld',(err)=>{
if(!err){
?// 03.文件寫入后,需要關(guān)閉文件
fs.close(fd,(err)=>{
if(!err){
? ? ? ? ? ? ? ? ? ? ? ? console.log('寫入成功!');
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? })
? ? ? ? ? ? }
? ? ? ? })
? ? }
})
(2)一般方式寫入文件 writeFile()
fs.writeFile('./file/b.txt','HelloWorld',{flag:'a'},(err)=>{
if(!err){
? ? ? ? console.log('異步:寫入成功!');
? ? }
})
九、try..catch
將可能會發(fā)生異常的代碼放在try中,如果程序發(fā)生異常,會跳轉(zhuǎn)到catch中執(zhí)行保護(hù)代碼,
使程序不至于就此終止。catch代碼塊可以傳遞一個參數(shù)e,里面保存的是發(fā)生異常的消息。
// 文件系統(tǒng)在實(shí)際開發(fā)中的用法:
try{
? ? let?num1?=?10
? ? let?num3?=?num1?+?num4
? ? console.log(num3);
}catch(e){
?//通常情況下,需要將錯誤信息寫入到日志文件中
?// console.log('上面的代碼發(fā)生了錯誤',e.message);
fs.writeFile('./file/log.txt',e.message+' 發(fā)生時間:'+(new?Date())+'\r\n',{flag:'a'},(err)=>{
if(!err){
? ? ? ? ? ? console.log('錯誤信息,寫入日志文件');
? ? ? ? }
? ? })
}
十、同步API和異步API
1、同步API
同步API:只有當(dāng)前API執(zhí)行完成后,才能繼續(xù)執(zhí)行下一個API。
同步API,可以通過返回值接收結(jié)果。
//同步API
function?fun1(){
? ? return?'大家好!我是一個同步方法'
}
//同步API,可以通過返回值接收結(jié)果
let?str1?=?fun1()
console.log(str1);// str1
2、異步API
異步API:當(dāng)前API的執(zhí)行不會阻塞后續(xù)代碼的執(zhí)行。
異步API時,直接寫一個回調(diào)函數(shù)作為參數(shù)傳進(jìn)入,這個函數(shù)接收異步API返回值。
//異步API
function?fun2(callback){
? ? setTimeout(() =>?{
? ? ? ? callback('大家好!我是一個異步方法')
? ? }, 1000);
}
//調(diào)用異步API時,直接寫一個回調(diào)函數(shù)作為參數(shù)傳進(jìn)入。
//回調(diào)函數(shù),通常會寫成箭頭函數(shù)
fun2(str?=>?console.log(str))
十一、Promise 對象
1、語法
ES6推出了一個全新的對象:Promise,該對象用于處理回調(diào)地獄。
Promise的構(gòu)造函數(shù)接收一個參數(shù),是函數(shù),并且傳入兩個參數(shù):resolve,reject,分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。
Promise對象的then()方法用來獲取成功的返回結(jié)果;catch()方法用來獲取失敗的返回結(jié)果。
function?myReadFile(path) {
return?new?Promise((resolve) =>?{
fs.readFile(path, (err,?r) =>?{
if?(!err) {
resolve(r.toString())
? ? ? ? ? ? }
? ? ? ? })
? ? })
}
myReadFile('./file/a.txt').then(r=>?{
if?(r==?'中國') {
? ? ? ? return?myReadFile('./file/e.txt')
? ? }
}).then(r=>?{
if?(r==?'賽虹橋街道') {
console.log(r);
? ? }
})
2、async和await
async關(guān)鍵字,用于定義異步函數(shù),異步函數(shù)中,可以使用await關(guān)鍵字,簡化then的步驟。await關(guān)鍵字提取Promise對象的返回的結(jié)果。
async?function?run() {
? ? let?a?=?await?myReadFile('./file/a.txt')
? ? if?(a?!=?'中國') return
? ? let?e?=?await?myReadFile('./file/e.txt')
? ? if?(e?!=?'賽虹橋街道') return
? ? console.log(e);
}
run()
十二、MongoDB數(shù)據(jù)庫
1、數(shù)據(jù)庫下載安裝
使用Node.js操作MongoDB數(shù)據(jù)庫需要依賴Node.js第三方包mongoose。
使用npm install mongoose命令下載。
2、啟動MongoDB
運(yùn)行net start mongoDB即可啟動MongoDB,否則MongoDB將無法連接。
[if !supportLists]3、[endif]導(dǎo)入mongoose和數(shù)據(jù)庫連接
使用mongoose提供的connect方法連接數(shù)據(jù)庫。注意:如果連接的數(shù)據(jù)庫(MySchool)不存在,會自動創(chuàng)建數(shù)據(jù)庫(MySchool)。
// 導(dǎo)入mongoose
let?mongoose?=?require('mongoose')
// 連接數(shù)據(jù)庫
mongoose.connect('mongodb://localhost/MySchool',
{ useNewUrlParser:?true,useUnifiedTopology:?true?})
.then(() =>?console.log('數(shù)據(jù)庫連接成功'))
.catch(err=>?console.log('數(shù)據(jù)庫連接失敗',?err));
4、創(chuàng)建表
(1)定義表規(guī)則
定義表規(guī)則:表里面的有哪些列,分別是什么數(shù)據(jù)類型。
① 基本寫法
// 定義student表規(guī)則
const?studentSchema?=?new?mongoose.Schema({
?//定義具體的表規(guī)則
? ? name:?String,
? ? age:?Number,
? ? sex:String,
? ? hobbies:[String],
? ? isVip:?Boolean
});
② 定義表里具體屬性的規(guī)范
在創(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)值
let?studentSchema?=?new?mongoose.Schema({
?//name屬性的規(guī)范
? ? name:{
type:String,// 類型是String
require:true,// 不允許為空
minlength:2,// 最小長度為2
maxlength:8// 最大長度為8
? ? },
? ? sex:{
? ? ? ? type:String,
default:'男'// 性別的默認(rèn)值是“男”
? ? },
? ? age:{
? ? ? ? type:Number,? ?
min:3,// 年齡的范圍是3-100
? ? ? ? max:100
? ? },
? ? hobbies:{
? ? ? ? type:[String],?
require:false// 愛好允許為空
? ? }
})
(2)創(chuàng)建表對象
注意:數(shù)據(jù)庫中的表名會自動改成復(fù)數(shù)格式(students)
const?Student?=?mongoose.model('Student', studentSchema)
[if !supportLists]5、[endif]向表中添加數(shù)據(jù)
方法(1) 通過表實(shí)例對象
① 創(chuàng)建表實(shí)例對象
// 5.1.
const?stu1?=?new?Student({
? ? name:?'張三',
? ? age:?20,
? ? sex:?'男',
? ? hobbies:?['學(xué)習(xí)','睡覺','打球'],
? ? isVip:true
});
② 表實(shí)例對象通過save方法將數(shù)據(jù)保存到數(shù)據(jù)庫的數(shù)據(jù)表中
stu1.save((err,result)=>{
? ? if(!err){
?//添加成功,打印添加的結(jié)果
? ? ? ? console.log(result);
? ? }
})
方法(2) create方法,通過回調(diào)函數(shù)返回結(jié)果
通過數(shù)據(jù)表的create的方法,直接向數(shù)據(jù)表中添加數(shù)據(jù)(通過回調(diào)函數(shù)返回結(jié)果)。
Student.create({
? ? name:?'李四',
? ? age:?22,
? ? sex:?'女',
? ? hobbies:?['看電視','睡覺','看電影'],
? ? isVip:false
},(err,result)=>{
if(!err){
console.log(result);
? ? }
})
方法(3) create方法,通過Promise對象返回結(jié)果
通過數(shù)據(jù)表的create的方法,直接向數(shù)據(jù)表中添加數(shù)據(jù)(通過Promise對象返回結(jié)果)。
Student.create({
? ? name:?'王五',
? ? age:?24,
? ? sex:?'男',
? ? hobbies:?['敲代碼','睡覺','寫字'],
? ? isVip:true
}).then(result=>{
console.log(result);
}).catch(err=>{
console.log(err);
})
6、查詢語句
(1)查詢?nèi)啃畔ind()
find方法返回的是數(shù)組。
// 查詢student表的全部數(shù)據(jù)
Student.find().then(r=>{
? ? console.log(r);
})
(2)根據(jù)條件查詢find(條件)
返回的是符合條件的數(shù)組。如果沒有滿足條件的結(jié)果,就返回一個空數(shù)組。
Student.find({name:'李白'}).then(r=>{
? ? console.log(r);
})
(3)返回表中的第一個對象findOne()
findOne方法返回的是對象。
Student.findOne().then(r=>{
console.log(r);
})
(4)根據(jù)條件查詢 findOne(條件)
查詢第一個滿足條件的,返回的是對象,如果沒有滿足條件的結(jié)果,就返回null。
Student.findOne({name:'李白'}).then(r=>{
? ? console.log(r);
})
(5)查詢某個范圍內(nèi)的數(shù)據(jù)
① 查詢大于某數(shù)值的數(shù)據(jù) $gt
// 查詢年齡大于20歲的學(xué)生信息
Student.find({age:{$gt:20}}).then(r=>{
console.log(r);
})
② 查詢大于某數(shù)值的數(shù)據(jù) $lt
// 查詢年齡小于20歲的學(xué)生信息
Student.find({age:{$lt:20}}).then(r=>{
console.log(r);
})
③ 查詢兩數(shù)之間的數(shù)據(jù) {$gt:num1,$lt:num2}}
// 查詢年齡在20歲到40歲之間的學(xué)生信息
Student.find({age:{$gt:20,$lt:40}}).then(r=>{
console.log(r);
})
④ 查詢兩數(shù)之間的數(shù)據(jù)(包括兩數(shù)) {$gte:num1,$lte:num2}}
// 查詢年齡在20歲到40歲之間的學(xué)生信息(包括20和40)
Student.find({age:{$gte:20,$lte:40}}).then(r=>{
console.log(r);
})
(6)根據(jù)正則表達(dá)式匹配查詢條件(用于模糊查詢)
$regex 正則,用于模糊查詢。
select方法,篩選查詢列。注意:_id列默認(rèn)會返回,如果不需要查詢id,就加上-_id。
// 查詢姓名中包含'劉'的學(xué)生信息,只返回name、sex、age列
Student.find({name:{$regex:/劉/i}}).select('name sex age -_id').then(r=>{
? ? console.log(r);
})
注意:如果正則條件是模板字符串,需要使用new RegExp()創(chuàng)建。
Student.find({ name:?{ $regex:?new?RegExp(`${name}`, 'i') } }).then(r=>?{res.send(r)})
(7)匹配包含
① $in 滿足其中一個元素的數(shù)據(jù)
?// 查詢愛好中包含‘睡覺’或‘學(xué)習(xí)’的學(xué)生信息
Student.find({hobbies:{$in:['睡覺','學(xué)習(xí)']}}).select('name sex age hobbies -_id').then(r=>{
? ? console.log(r);
})
② $all 滿足所有元素的數(shù)據(jù)
// 查詢愛好中包含‘睡覺’和‘學(xué)習(xí)’的學(xué)生信息
Student.find({hobbies:{$all:['睡覺','學(xué)習(xí)']}}).select('name sex age hobbies -_id').then(r=>{
console.log(r);
})
(8)對查詢結(jié)果排序sort()
① 升序排列
// 根據(jù)年齡升序查詢學(xué)生信息
Student.find().sort('age').select('name sex age -_id').then(r=>{
? ? console.log(r);
})
② 降序排列
// 根據(jù)年齡降序查詢學(xué)生信息
Student.find().sort('-age').select('name sex age -_id').then(r=>{
? ? console.log(r);
})
③ 根據(jù)性別升序,再根據(jù)年齡降序
// 先返回相同性別的學(xué)生,相同性別的學(xué)生再根據(jù)年齡降序
Student.find().sort('sex -age').select('name sex age -_id').then(r=>{
? ? console.log(r);
})
(9)分頁查詢
skip()跳過多少條數(shù)據(jù);limit()限制查詢數(shù)量。
// 每頁2條數(shù)據(jù),顯示第2頁
let?pageIndex?=?2//定義頁碼
let?pageSize?=?2//定義每頁數(shù)量
Student.find().skip((pageIndex-1)*pageSize).limit(pageSize).select('name sex age -_id').then(r=>{
console.log(r);
})
(10)修改指定對象的信息
① 修改單個對象 updateOne()
updateOne({查詢條件}, {要修改的值})
Student.updateOne({_id:'617f5d951df9a826303015fa'},{name:'張飛',age:38}).then(r=>{
console.log(r);
})
② 修改多個對象 updateMany()
updateMany({查詢條件}, {要更改的值})
Student.updateMany({sex:'女'},{age:25}).then(r=>{
? ? console.log(r);
})
(11)刪除數(shù)據(jù)
① 刪除單個 findOneAndDelete()
刪除成功后,返回刪除的對象
Student.findOneAndDelete({ _id:?'617f5d951df9a826303015fa'?}).then(r=>?{
? ? console.log(r)
})
② 刪除單個 deleteOne()
刪除成功后,返回刪除的數(shù)量
Student.deleteOne({ _id:?'617f5d951df9a826303015fc'?}).then(r=>?{
? ? console.log(r)
})
③ 刪除多個 deleteMany()
刪除成功后,返回刪除的數(shù)量
Student.deleteMany({sex:'女'}).then(r=>{
console.log(r);
})
十三、Express框架
1、定義
Express是一個基于Node平臺的web應(yīng)用開發(fā)框架,它提供了一系列的強(qiáng)大特性,幫助你創(chuàng)建各種Web應(yīng)用。
使用npm install express 命令進(jìn)行下載。
2、基本步驟
(1)導(dǎo)入express
let?express?=?require('express')
(2)通過express函數(shù),創(chuàng)建并返回一個web服務(wù)器對象
let?app?=?express()
(3)啟動服務(wù)器,并監(jiān)聽一個端口號(端口號是自定義的)
app.listen(8848,()=>{
? ? console.log('服務(wù)器成功開啟,端口號是8848');
})
3、中間件
(1)定義
中間件就是一堆方法,可以接收客戶端發(fā)來的請求、可以對請求做出響應(yīng),也可以將請求繼續(xù)交給下一個中間件繼續(xù)處理。
(2)app.use中間件用法
app.use 匹配所有的請求方式,可以直接傳入請求處理函數(shù),代表接收所有的請求。所有的請求,都會先走use,作用是攔截器。
實(shí)際開發(fā)中,我們用use中間件方法里面去判斷用戶的權(quán)限,從而確定該用戶能否繼續(xù)請求相關(guān)的接口。
app.use((req,res,next)=>{
?//表示:允許跨域請求
?res.setHeader('Access-Control-Allow-Origin','*')
?//next方法,表示繼續(xù)往下執(zhí)行
? ? next()
})
4、跨域
(1)定義
同源策略:協(xié)議名,主機(jī)名(域名或ip地址),端口號必須完全相同。違背同源策略就是跨域。
ajax請求,必須要遵循同源策略。
(1)解決跨域
設(shè)置響應(yīng)頭,允許跨域請求。
?response.setHeader('Access-Control-Allow-Origin','*')
(2)允許自定義請求頭信息
響應(yīng)頭*表示所有類型的頭信息都可以接受。
?response.setHeader('Access-Control-Allow-Headers','*')
5、get請求接口
(1)get請求參數(shù)的獲取
req.query接收前端傳遞的GET請求參數(shù),框架內(nèi)部會將GET參數(shù)轉(zhuǎn)換為對象并返回。
(2)定義get請求接口
req是請求對象,里面保存的是客戶端傳過來的請求參數(shù)。
res是響應(yīng)對象,用于給客戶端響應(yīng)結(jié)果。
res.send()將結(jié)果返回給前端。
app.get('/getStudents',(req,res)=>{
?res.send('hello')
})
6、post請求接口
(1)post請求參數(shù)的獲取
req.body接收前端傳遞過來的POST請求參數(shù)。
接收POST請求參數(shù),服務(wù)器需要進(jìn)行設(shè)置。
通過express.json()中間件,解析表單中的JSON格式數(shù)據(jù)。
通過express.urlencoded()中間件,解析表單中的url-encoded格式數(shù)據(jù)。
// 設(shè)置允許接收json格式的數(shù)據(jù)({"name":"張三","age":20})
app.use(express.json())
// 設(shè)置允許接收urlencoded格式的數(shù)據(jù)("name=張三&age=20")
app.use(express.urlencoded({extended:false}))
(2)定義post請求接口
app.post('/add', (req,?res) =>?{
console.log(req.body);// 接收請求參數(shù)
?res.send('hello')
})
十四、AJAX
1、原生AJAX
(1)GET請求
GET請求的參數(shù),使用?直接拼接在url地址后面,如果有多個參數(shù)使用&符號。
參數(shù)例如:name=${name}&pageIndex=${pageIndex}
// 01.創(chuàng)建xhr對象
let?xhr?= new?XMLHttpRequest()
// 02.初始化請求
xhr.open('GET',`http://localhost:5566/students?name=${name}`)
// 03.發(fā)送請求
xhr.send()
// 04.監(jiān)聽事件,并接收結(jié)果
xhr.onreadystatechange?= function(){
//請求完成
? ? ?if(xhr.readyState===4){
//請求成功
? ? ? ? ?if(xhr.status===200){? ? ?
console.log(xhr.response);//打印響應(yīng)結(jié)果
? ? ? ? ?}
? ? ?}
?}
(2)POST請求
① 設(shè)置Content-Type請求頭
POST請求時,需要設(shè)置Content-Type請求頭,告訴服務(wù)器傳遞的數(shù)據(jù)格式。
如果是urlencoded格式的數(shù)據(jù):
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
如果是json字符串格式的數(shù)據(jù):
xhr.setRequestHeader('Content-Type','application/json')
② 參數(shù)傳遞
post請求的參數(shù),在發(fā)送時傳遞。
傳遞urlencoded格式的數(shù)據(jù):
xhr.send(`name=polo&age=35`)
傳遞json字符串格式的數(shù)據(jù):
let?params?= {
? ? ?name:name,
hobbies:hobbies.split(',')//愛好,轉(zhuǎn)為數(shù)組
?}
xhr.send(JSON.stringify(params))// 將對象轉(zhuǎn)為json格式字符串
③ 基本格式
??let?xhr?= new?XMLHttpRequest()
? xhr.open('POST','http://localhost:5566/deleteStudent')
? xhr.setRequestHeader('Content-Type','application/json')
xhr.send(JSON.stringify({_id:id}))
? xhr.onreadystatechange?= function(){
? ? ? if(xhr.readyState===4){
? ? ? ? ? if(xhr.status===200){
? ? ? ? ? ? ? ? console.log(xhr.response);
? ? ? ? ? }
? ? ? }
}
[if !supportLists]2、[endif]jQuery AJAX
[if !supportLists](1)[endif]GET請求
$.get(請求地址, {參數(shù)名: 參數(shù)值}, 回調(diào)函數(shù))
$.get('http://localhost:5566/students',{name:"張三"},r=>{
console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)
? })
[if !supportLists](2)[endif]POST請求
$.post(請求地址, {參數(shù)名: 參數(shù)值}, 回調(diào)函數(shù))
$.post('http://localhost:5566/deleteStudent',{_id:id},r=>{
console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)
? })
[if !supportLists](3)[endif]通用型方法ajax
① get請求
? ? ? ? ? ? $.ajax({
type:?"get",// 請求的接口地址
url:?url,// 請求方式get 或 post
dataType:?"json",?// 返回的數(shù)據(jù)類型
?// 請求成功后的回調(diào)函數(shù)
success:?function?(r) {
console.log(r)
? ? ? ? ? ? ? ? },
?// 請求失敗后調(diào)用的函數(shù)
error:?function?(err) {
? ? ? ? ? ? ? ? ? ? console.log('請求錯誤')
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
② post請求
發(fā)送post請求時,如果請求參數(shù)是json字符串格式,需要設(shè)置contentType請求頭為'application/json'。contentType默認(rèn)值 "application/x-www-form-urlencoded"。
let?params?= {
? ? ?????name:name,
? ? ?????hobbies:hobbies.split(',')
???}
$.ajax({
url:url,// 請求的接口地址
type:'POST',// 請求方式get 或 post
data:JSON.stringify(params),// 請求的參數(shù)
? ? ? ? ?contentType:'application/json',
success:function(r){
console.log(r);// r表示請求成功時返回的結(jié)果數(shù)據(jù)
? ? ? ? ?}
? ? })
3、axios AJAX
(1)引入axios庫
src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js">
(2)GET請求
① get請求的參數(shù)可以直接用?拼接在URL中。
axios.get('/user?ID=12345').then(function?(response) {
console.log(response);
}).catch(function?(error) {
console.log(error);
? ? ? ? });
② get請求的參數(shù)可以寫在params對象中。
注意:get請求的返回結(jié)果包含很多信息,需要將結(jié)果中的data解構(gòu)出來。data中存放的才是需要的數(shù)據(jù)。
? ? ? axios.get('http://localhost:5566/students', {
? ? ? ? ? ? params:?{
? ? ? ? ? ? ???name:name
? ? ? ? ? ?}
}).then(({?data}) =>?{
? ? ? ? ? ?console.log(data)
? ? ? })
(3)POST請求
post請求參數(shù)直接寫在對象中傳入。
let?params?= {
? ? ?????name:name,
? ? ?????hobbies:hobbies.split(',')
?}
axios.post(`http://localhost:5566/deleteStudent`, params?).then(({?data}) =>?{
? ? ? ? ?console.log(data)
})
(4)通用方式axios
? ? ? ? ? ? axios({? ? ?
method:?'POST',//請求方法
url:?'/axios-server',//url
params:?{//請求參數(shù)
? ? ? ? ? ? ? ? ? ? vip:?10,
? ? ? ? ? ? ? ? ? ? level:?30
? ? ? ? ? ? ? ? }, ? ? ? ? ?
headers:?{//設(shè)置請求頭信息
? ? ? ? ? ? ? ? ? ? a:?100,
? ? ? ? ? ? ? ? ? ? b:?200
? ? ? ? ? ? ? ? },
?//請求體參數(shù)
? ? ? ? ? ? ? ? data:?{
? ? ? ? ? ? ? ? ? ? username:?'admin',
? ? ? ? ? ? ? ? ? ? password:?'admin'
? ? ? ? ? ? ? ? }
}).then(response=>?{
console.log(response);
?//響應(yīng)狀態(tài)碼
console.log(response.status);
?//響應(yīng)狀態(tài)字符串
console.log(response.statusText);
?//響應(yīng)頭信息
console.log(response.headers);
?//響應(yīng)體
console.log(response.data);
? ? ? ? ? ? })
4、fetchAJAX
(1)fetch定義
fetch是一個瀏覽器內(nèi)置的全新的請求API。之前我們使用的jquery和axios的請求方法只是對XMLHttpRequest對象的封裝。
fetch()函數(shù)的第一個參數(shù)是url地址,第二個參數(shù)是配置對象。
(2)GET請求
GET請求的參數(shù),使用?直接拼接在url地址后面,如果有多個參數(shù)使用&符號。
fetch(`http://localhost:5566/students?stuName=${stuName}`,{
method:'GET',//設(shè)置請求方式(默認(rèn)是GET)
}).then(response=>{
?// 第一個then,用于返回請求的狀態(tài)信息(檢查請求是否成功等等)
?// 再通過請求狀態(tài)對象的.json()方法,返回請求結(jié)果
returnresponse.json()
}).then(r?=>{
console.log(r)// 返回請求結(jié)果
?})
(3)POST請求
發(fā)送post請求時,請求參數(shù)如果是json字符串格式,需要配置請求頭headers,設(shè)置Content-Type為'application/json'。
? ? ? ? ? ? let?params?= {
? ? ? ? ? ? ? ? name:name,
? ? ? ? ? ? ? ? hobbies:hobbies.split(','),
? ? ? ? ? ? }
? ? ? ? ? ? fetch(url,{
? ? ? ? ? ? ? ? method:'POST',
?//配置請求頭信息
? ? ? ? ? ? ? ? headers:{
? ? ? ? ? ? ? ? ? ? 'Content-Type':'application/json'
? ? ? ? ? ? ? ? },
body:JSON.stringify(params)// post請求參數(shù)
}).then(r=>{
returnr.json()
}).then(r=>{
console.log(r)// 返回請求結(jié)果
? ? ? ? ? ? })