文章出處
文章列表
上一篇介紹了如何用express搭建起服務端MVC的開發架構,本篇我們來詳細介紹一下這個Model層,也就是數據庫訪問層。包含如何使用mongodb搭建數據庫,以及如何使用mongoose來訪問數據。
mongodb的安裝和啟動
首先我們得安裝mongodb,先去官網( http://www.mongodb.org/downloads)下載安裝包,我的開發環境是Windows,所以下載Windows下的iso文件,根據提示一路安裝完畢即可,沒什么需要特別選擇的。
安裝完后,為了能在cmd中全局都能啟動mongodb,我們需要配置環境變量,將安裝目錄下的bin目錄配置在系統變量中,如圖:
![](https://imageproxy.pixnet.cc/imgproxy?url=https://images2015.cnblogs.com/blog/520134/201602/520134-20160201235148882-952220846.png)
接下來,新建一個目錄,用于存放數據庫文件。我新建的目錄為D:\mongodb\data\db,然后運行cmd,執行命令mongod --dbpath D:\mongodb\data\db,這個時候mongodb就運行起來了,我們就可以用程序來連接數據庫了。
連接數據庫
mongodb的默認端口是27017,我們在項目中有一個models文件夾,里面放置與數據庫連接的數據模型,其中有一個mongodb.js,內容很簡單:
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/QuestionMaker'); exports.mongoose = mongoose;
是標準的commonjs模塊寫法,先引用mongoose模塊,然后連接數據庫,對外暴露mongoose模塊。可以看到我們在代碼中去訪問本地的QuestionMaker數據庫。那么首先我們得有這個數據庫才行。運行cmd,創建一個數據庫
use QuestionMaker
db.createCollection("counters")
此命令會創建一個名為QuestionMaker的數據庫,并在該庫創建一個集合counters(這個集合我們后續會用到),必須得這么寫,否則數據庫無法創建。驅動模塊寫好了,我們在其他模塊中引用該模塊后,就可以連接到數據庫了。
使用mongoose操作數據庫
我們看到上面用了一個叫做mongoose的模塊,它是一個nodejs模塊,mongoose提供了Schema、Model、Documents對象,用它可以更加直觀的操作數據庫,所以很多人喜歡這個模塊,我們項目中也用它來操作數據庫。
為了能以我們熟悉的面向對象的方式來訪問數據庫,我們先根據試題的數據結構來創建一個Schema:
var QuestionSchema = new Schema({ id: String, qtype: Number, name: String, content: String, options: [ { name: String } ], answer: String });
Schema可以理解為一個模板,根據此模版,我們可以用mongoose.model來創建出一個Question類,代碼如下:
var Question = mongodb.mongoose.model("Question", QuestionSchema);
利用Question類示例化出的對象帶有很多方法用來訪問/操作數據庫,如save方法,可以保存一條文檔,也就是document(mongodb中的概念,類似我們以前概念中的一條記錄)。
為了盡可能少的對外暴露數據(封裝性),我新建了一個QuestionDAO對象,也就是仿造java中的概念,加一個DAO層,用來提供數據訪問。對外暴露的方法都定義在這個對象上,例如保存記錄和更新記錄的代碼如下:
//保存試題 QuestionDAO.prototype.save = function(obj, callback){ var instance = new Question(obj); instance.save(function(err){ callback(err, null); }); } //更新試題 QuestionDAO.prototype.update = function(obj, callback){ Question.findByIdAndUpdate(obj._id, obj, {}, function(err){ callback(err, null); }); }
用了mongoose提供的save方法和findByIdAndUpdate方法,每一個操作之后都可以傳回調函數,這樣我們就能把數據庫訪問的結果返回給controller層了。
另外,根據業務需求,我們就可以寫更多的方法了,如項目中的list、get、remove,分別用來獲取試題列表、獲取試題、刪除試題。其中list方法中還實現了分頁返回數據。
mongodb實現id自增
id自增是數據庫的一個常見需求,在mysql中,只要指定字段auto_increment即可,在mongodb中,沒有這樣的方法,所以必須得在代碼中實現才行。我們按照官方給出的解決方法,實現questions集合的id自增。
id自增功能需要一個輔助的集合來完成,就是我們之前新建好的counters,用來記錄當前的id值為多少。在mongodb命令行中執行db.counters.save({_id: "questionid", seq: 0})完成初始化。_id是mongodb默認提供的一個字段,我們這里賦值為questionid,是為了做一個標記,以便在后面能夠查找出這條記錄。
然后在question.js中創建CounterSchema并生成一個Counter類,用來操作counters集合,代碼如下:
var CounterSchema = Schema({ _id: {type: String, required: true}, seq: { type: Number, default: 1 } }); var Counter = mongodb.mongoose.model("Counter", CounterSchema);
然后,在QuestionSchema的save方法之前,我們應該先去counters中獲取最新id,可以用pre方法來實現,代碼如下:
QuestionSchema.pre('save', function(next) { var doc = this; Counter.findByIdAndUpdate({_id: 'questionid'}, {$inc: { seq: 1} }, function(error, counter) { if(error) return next(error); doc.id = counter.seq; next(); }); }); QuestionSchema.set('toObject', { getters: true });
如此一來,每次Question執行save方法的時候,都會調用這個函數,從而獲取到遞增后的最新id。
備份和導入
數據庫的備份和導入當然是必不可少了,比如大家可以拿這我的備份文件直接導入來練習,這樣就省去了一步一步創建的步驟。
備份數據庫可以使用mongodump命令,用法如下:
mongodump -h dbhost -d dbname -o dbdirectory
導入已有的數據庫可以使用mongostore命令,用法如下:
mongorestore -h dbhost -d dbname –directoryperdb dbdirectory
具體的參數可以在網上搜索,文章很多,此處不再詳細說明。
客戶端工具
mongodb有沒有像mysql那樣的客戶端工具呢?當然有啦,我使用的是robomongo這個工具,簡單好用,界面如下,大家可以嘗試使用。
![](https://imageproxy.pixnet.cc/imgproxy?url=https://images2015.cnblogs.com/blog/520134/201602/520134-20160201235514132-1662157714.png)
使用MEAN技術棧開發web應用系列三部曲就到這里了,再次附上練手項目的地址:https://github.com/Double-Lv/QuestionMaker
另外,本系列文章只是一個入門級別的介紹,所寫的代碼以及數據庫的設計基本上都屬于”玩具代碼“,寫一個自己玩的項目還行。在實際的項目中,我們還得考慮各種因素,性能、負載等等,更多話題有待研究。
文章列表
全站熱搜