知識點
1、node
2、express
3、Mongoose
4、ES6
連接配接資料庫
mongodb的位址我們一般需要配置在config檔案中,做環境隔離,畢竟我們開發、測試、準生産、生産環境連接配接的資料庫位址是不一樣的,配置在config檔案中,我們直接通過啟動指令或者打包指令就可以切換到我們需要的mongodb位址,是開發必不可少的。
你可以使用
mongoose.connect()
方法連接配接 MongoDB 。
//資料庫位址
api:{
db:mongodb://賬戶:密碼@位址:端口/資料庫名字
}
//封裝連接配接資料庫代碼
import mongoose from 'mongoose';
import errorEnum from './errorEnum';
const connect = () => {
return new Promise((res, rej) => {
try {
mongoose.connect(__API__.db, (err) => {
if (err) {
rej(errorEnum.DB_CONNECT())
} else {
res();
}
})
} catch (err) {
rej(errorEnum.DB_CONNECT())
}
})
}
export {connect}
其中
errorEnum
是我們集中處理異常碼的檔案,看一下代碼,我們把所有需要抛給前端的錯誤碼在這處理,清晰便于維護。
import resh from '../helpers/responseHelper';
const DB_CONNECT = () => {
return resh.failureResponse('連接配接資料庫失敗', '1001')
}
...
export default {DB_CONNECT}
responseHelper
中我們做的是把傳回給前端接口的
json
格式進行封裝,按照上文的異常情況傳回給前端的應該是
{desc:'連接配接資料庫失敗',code:'1001',body:{}}
,前端就可以根據錯誤碼做資料庫連接配接失敗的異常處理機制。
const failureResponse = (desc, code) => {
return {
desc: desc,
code: code,
body: {}
}
}
...
export default {
failureResponse,
...
}
使用者注冊
1、使用者輸入賬号(郵箱)密碼注冊賬戶
2、拿賬号在資料庫中查詢賬号是否已經存在,存在抛異常
3、賬号在資料庫中沒有存在,則把賬号資訊存入資料庫,存成功傳回注冊成功
定義一個Schema 、建立一個Model
Mongoose 的一切始于 Schema。每個 schema 都會映射到一個 MongoDB collection ,并定義這個collection裡的文檔的構成。
//我是 UserRegister.js
import mongoose from 'mongoose';
const registerSchema = new mongoose.Schema({
id: String,
mail: String,
password: String,
role:Array
}, {collection: 'user_register'});
module.exports = mongoose.model('user_register', registerSchema);
document 裡每個屬性的類型都會被轉換為 在
blogSchema
裡定義對應的
SchemaType如上
mail
屬性會被轉化為SchemaType String,
role
屬性會被轉化為SchemaType Array,其實簡單的說就是存在資料庫中的類型,我們存的時候需要傳的類型。
我們要把 schema 轉換為一個 Model 使用
mongoose.model(modelName, schema)
函數,如上
module.exports = mongoose.model('user_register', registerSchema);
就是把
registerSchema
轉化為Model,以後的增删改查都要通過這個Model實作。
user_register
是在資料庫中的表名,如下圖,user_register表裡邊的資料結構跟schema中我們定義的對應一下,其中_id是mongodb自己生成的,是個對象,支援排序。

圖1.資料庫顯示
資料庫 增、查、改、删
find
方法可按條件查詢資料庫
save
提供往資料庫新增一條資料的方法,繼續以使用者注冊為例
下邊接口的入參:
{mail:'[email protected]',password:'123456'}
增加完畢以後就如 圖1 中所示,在資料庫中插入一條資料,但是
role
是
[]
//定義Schema 建立Model的檔案
import Register from '../model/UserRegister';
const register = (req,res)=>{
const _params = req.body.data;//取得接口傳過來的資料
//此處省略對參數校驗的過程,假設傳過來的都是合法參數,但實際項目我們還是需要校驗的
const _findParams = {mail:_params.mail};
//用賬号去資料庫中查找賬号是否已經注冊
Register.find(_findParams, (err, data) => {
if ( err ) {
//抛出異常
} else {
//data是我們查資料庫得到的資料,沒有查到為[]
if(data == 0){
const register = new Register({
..._params,
});
register.save((err)=>{
if(err){
//資料庫異常
}else{
//儲存成功
mongoose.disconnect();
}
});
}else{
//提示使用者該賬戶已經注冊
}
}
});
}
export default {register}
update
提供了更新資料庫的方法,也就是我們說的 “改”
用法
Model.update(condition,doc,[options],[callback]);
condition
:更新的條件,要求是一個對象。
doc
:要更新的内容,要求是一個對象。
[options]
:可選參數,要求也是一個對象。
[callback]
:可選參數,要求是一個回調函數。
如下接口的入參:
{id:'10011',role:['user']}
接口提供的是給一個使用者配置設定權限的服務,初始注冊權限為
[]
//定義Schema 建立Model的檔案
import Register from '../model/UserRegister';
const setAuthority = (req, res) => {
const _params = req.body.data;
const _id = _params.id;
//根據id查到對應的資料,将role參數更新
Register.update({_id: _id}, {$set: {role: _params.role}}, (err) => {
if (err) {
//資料庫異常
} else {
//修改成功
}
mongoose.disconnect();
})
}
export default {setAuthority}
$set
用來指定一個鍵并更新鍵值,若鍵不存在并建立
登入使用
update
登入的特殊性要求我們必須去更新資料庫,畢竟我們不希望同樣的賬戶可以到處登入,我們必須保證一個賬号在登入表裡隻有一條記錄,這樣後登入的就覆寫先登入的,先登入的再次請求接口就會報
token
異常了。
存登入資訊我們需要另一張表,就是說我們需要一個新的Schema,Model,上文已經介紹了怎麼建立,這裡就不重複說明了。
{mail:'[email protected]',password:'123456'}
//定義Schema 建立Model的檔案
import Login from '../model/UserLogin';
import Register from '../model/UserRegister';
const login=(req,res)=>{
const _params = req.body.data;//取得接口傳過來的資料
//此處省略參數校驗過程
//先去系統資料庫查詢目前的登入的賬号是否注冊
Register.find(_findParams, (err, data) => {
if ( err ) {
//抛出異常
} else {
//data是我們查資料庫得到的資料,沒有查到為[]
if(data == 0){
//提示使用者沒有注冊
}else{
const _user = data[0];//取到注冊資料
//比較使用者輸入的密碼和系統資料庫裡的密碼是否相等
if(_params['password']===_user['password']){
//生成token
const _token = uuid.v1();
const _params = {
..._value,
role: _user.role,//把注冊裡邊的角色也儲存到登入表裡邊
token: _token
};
//賬号和密碼都比對,這個時候使用系統資料庫裡的id去登入表裡邊查詢資料,沒有查到就建立,查到就更新。
Login.upadate((_id:_user['_id']),{$set:{..._params}},{usert:true},(err)=>{
if(err){
//資料庫錯誤
}else{
//儲存成功 把token和role傳回
}
mongoose.disconnect();//斷開資料庫連接配接
}
}else{
//密碼錯誤
}
}
}
});
}
upsert
boolean,如果不比對,是否建立文檔預設false,上邊代碼中用
upsert
是為了如果沒有在登入表中查到登入資訊就新增一條登入資料,如果查到了就更新資料。
擴充知識點
uuid
提供生成唯一辨別的兩個方法
npm install uuid --save
uuid.v1()
是基于時間戳生成的uid
uuid.v4()
是随機生成的uid
兩者相比較當然是
v1
更好用了,
v4
還是有重複的可能
remove
提供了删除資料的方法
以登入為例子,我們拿到token去登入表裡查使用者的登入資訊,查到了就删除。
{token:'123'}
//定義Schema 建立Model的檔案
import Login from '../model/UserLogin';
//登出
const logout = (req, res) => {
const _params = req.body.data;//取得接口傳過來的資料
//使用token去查找
Login.remove({token: _params.token}, (err) => {
if (err) {
//資料庫異常
} else {
//删除成功
}
})
}
export default {
logout
}
補充:前端在調用登出接口的時候一定要異步調用,前端自己要做清除緩存,跳轉登入頁面的操作,隻是通知背景我退出了,即使接口調用失敗前端也應該正常退出,下次登入的話就更新資料庫呗。
如果前端等到登出接口傳回成功再做操作,有幾率使用者一直退出不了。