国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Mabolo: 輕量級的 MongoDB ORM

verano / 996人閱讀

摘要:例如它使用了一些黑科技來阻止用戶修改從數據庫查出的文檔。我發現我其實只需要的一小部分功能,于是我自己編寫了我對它的定位是一個輕量級無黑科技的它完成于年初,目前已被使用到了我的大部分個人項目中。

一開始我像很多人一樣使用 Mongoose 作為 ORM, 但時間長了我發現了 Mongoose 的一些不理想的地方。

Mongoose 通過定義 Setter 的方式記錄了對文檔的每一次修改,以便可以用 save 方法將文檔無沖突地儲存在數據庫中。但我在實際使用中發現,我很少會使用這個功能,每當對文檔進行更新的時候,幾乎都是直接使用 MongoDB 的原子性操作符($set 等)。Mongoose 在這個功能上下了很大功夫,也增加了很多額外的約束。例如它 使用了一些黑科技 來阻止用戶修改從數據庫查出的文檔。而我希望從數據庫中查出文檔后進行一些加工,向文檔上儲存一些額外的數據來供渲染頁面時使用(但不儲存到數據庫),本來我們在 JavaScript 這樣的語言中是期待一個對象是可以被隨意修改的,但在 Mongoose 中卻不可以。

我發現我其實只需要 Mongoose 的一小部分功能,于是我自己編寫了 Mabolo, 我對它的定位是一個輕量級、無黑科技的 ORM. 它完成于 2015 年初,目前已被使用到了我的大部分個人項目中。

Mabolo 用 300 行代碼實現了一個 ORM 最核心的一些功能:為數據集合定義字段的類型、驗證文檔字段的合法性、定義類方法和實例方法、嵌入式的文檔和數組、原子性地更新整個文檔、同時兼容 Promise 和 callback 風格的 API.

Mabolo 幾乎沒有使用什么黑科技,每個 Model 都是一個普通的 JavaScript 構造函數,而每個文檔則都是由這個構造函數生成的實例 —— 除了幾個用來保存內部狀態的不可枚舉屬性之外和普通的對象沒有任何區別。

接下來我來談一談 Mabolo 中的幾個實現細節。

定義 Model

在 Mongoose 中,要先創建 Mongoose 實例(即代表一個數據庫連接)才能根據它來創建 Model, 但這樣會造成 Model 定義依賴于這個全局的數據庫連接。而在 Mabolo 中,可以先創建與實例無關的 Model, 然后再將其綁定到 Mabolo 實例上:

User.coffee:

Mabolo = reuqire "mabolo"
module.exports = Mabolo.model "User",
  name: String

app.coffee

Mabolo = reuqire "mabolo"
mabolo = new Mabolo "mongodb://localhost/test"
User = mabolo.bind require "./User"

即使 Model 還沒被綁定到 Mabolo 實例上,也是可以執行查詢的,這些插件會被阻塞,直到 Model 被綁定到一個數據庫連接上。

實現上,Mabolo.model 會創建一個繼承(CoffeeScript 的 extends)自 AbstractModel 的類,作為 Model 來使用。在綁定時,Mabolo.bind 會調用 Model 上的 bindCollection 函數,這個函數會 resolve 一個內部的 Promise, 讓對數據庫的操作開始執行。

嵌入式文檔

Mabolo 中 Model 的字段定義,既可以是基本類型,也可以是另一個 Model, 還可以是基本類型或 Model 的數組。

Token = mabolo.model "Token",
  code: String

User = mabolo.model "User",
  tokens: [Token]

在保存文檔到數據庫時,Mabolo 會調用 Model::transform 構造字段定義中的嵌入式文檔,這樣才可以運行定義在嵌入式文檔上的字段驗證。而在從數據庫取出文檔時,也會構造字段定義中所描述的嵌入文檔, 以便用戶調用嵌入文檔上的實例方法。

下一步會支持在嵌入文檔上運行 update 和 remove 方法。主要實現方法是 Model::transform 會在構造出的嵌入文檔上儲存父文檔和在父文檔中的位置,以便 update 時為查詢和更新中的字段名加上前綴。

再之后會支持文檔中的引用關系,在從數據庫中取出文檔時,Mabolo 會自動取出被引用到的文檔,這個過程被稱為「填充」,用戶也可以自己定義更復雜的填充規則。

原子性地更新文檔

Mabolo 使用了和 Mongoose 類似的技術來原子性地更新整個文檔,即在每次更新時都為文檔設置一個版本號(在 Mabolo 中是一個隨機的字符串),在進行原子更新時會將當前版本號作為一個查詢條件來運行更新,如果沒有成功(版本號被另一個操作修改了),會從數據庫中查出最新的文檔,重放修改然后再一次嘗試提交。

user.modify (user) ->
  Q.delay(1000).then ->
    user.age = 19
.then ->

Mabolo 使用了一種更簡單的方式實現重放修改 —— 即要求用戶傳入一個無副作用的修改函數,這個函數會在每次重放修改的時候被調用一次。應該說這只是一種不推薦大量使用的備選方案,更好的做法是直接使用 MongoDB 的原子操作符:

user.update
  $set:
    age: 19

https://jysperm.me/2015/06/mabolo-mongodb-orm/

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/18767.html

相關文章

  • 2015 年度小結(技術方面)

    摘要:因為路由層面受業務影響很大,經常修改一些功能的行為,所以后來大部分測試都是針對層面的單元測試。在我了解的過程中,我發現中文網絡上對的討論非常分散,于是我創建了中文社區,到年末已經有個注冊用戶和個帖子了。 https://jysperm.me/2016/02/programming-of-2015/ 從 2014 年末開始開發的一個互聯網金融項目終于在今年三月份上線了,這是一個 Node...

    宋華 評論0 收藏0
  • 2015 年度小結(技術方面)

    摘要:因為路由層面受業務影響很大,經常修改一些功能的行為,所以后來大部分測試都是針對層面的單元測試。在我了解的過程中,我發現中文網絡上對的討論非常分散,于是我創建了中文社區,到年末已經有個注冊用戶和個帖子了。 https://jysperm.me/2016/02/programming-of-2015/ 從 2014 年末開始開發的一個互聯網金融項目終于在今年三月份上線了,這是一個 Node...

    Nosee 評論0 收藏0
  • ORM-像對象一樣對待數據

    摘要:顧名思義,就是將關系型數據庫與中的對象關聯起來,提供了一種操作數據的簡便方式,相當于對數據庫加了一層更友好的接口。新增數據對象方法方法直接創建數據對象,需要調用方法保存到數據庫中。 咱們編程教室有不少同學,學完了基礎課程,掌握了一定的編程能力,開始做項目了。然后很可能遇到一個問題:管理數據。課程里有講過用文件保存數據,還有 pickle 、 csv 等模塊輔助。但對于稍微復雜一點的數據...

    U2FsdGVkX1x 評論0 收藏0
  • 微信公號DIY:MongoDB 簡易ORM & 公號記賬數據庫設計

    摘要:然后又介紹了基于的公號賬本應用的數據庫設計。歡迎關注公號四月試用。 前兩篇 微信公號DIY 系列: 微信公號DIY:一小時搭建微信聊天機器人 微信公號DIY:訓練聊天機器人&公號變身圖片上傳工具 介紹了如何使用搭建&訓練聊天機器人以及讓公號支持圖片上傳到七牛,把公號變成一個七牛圖片上傳客戶端。這一篇將繼續開發公號,讓公號變成一個更加實用的工具賬本(理財從記賬開始)。 代碼: 項目代...

    Backache 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<