Node.js ORM 數據操作中間件 Waterline

jopen 9年前發布 | 16K 次閱讀 Waterline Node.js 開發

 

這兩天在看 Sails.js 的時候,偶然看到了它使用的是 Waterline 來實現數據庫的操作,發現它和 Sails.js 為同一團隊所開發。翻了一下文檔,感覺在中小型項目中使用,的確可以提升開發效率。

Java 中的 Hibernate 框架的一個重要功能便是將數據庫中的數據與 Java 中的對象進行映射,被稱為 ORM (Object Relational Mapping)。Node.js 里常用的 Mongoose ,便是將 MongoDB 的文檔,映射為 JavaScript 的對象,而 Waterline 則是一個支持多種數據庫的 Mongoose ,使得可以用一樣的代碼來實現對多種數據庫的操作,無論是關系數據庫還是文檔數據庫,都可以直接使用對象的方法來進行增刪改查操作。

功能與特點

  • 廣泛的數據庫支持 :支持幾乎所有的主流關系數據庫和文檔數據庫
  • 脫離 SQL :對于習慣了使用 Mongoose 的程序員,如果要去使用 SQL 操作關系數據庫,肯定會有點費解, Waterline 可以像 Mongoose 一樣使用對象的方法來實現關系數據庫的操作
  • 屏蔽不同數據庫的差別 :對于大部分情況下,你根本不用關心操作的是 MySQL 還是 MongoDB。比如 MongoDB 中并沒有數字自增(Auto Increment)的功能,但 Waterline 使用 autoPK 來為 MongoDB 實現了自增
  • 易于理解的符號 :在 Mongoose 中,大于和小于得使用$gt/$lt來表示,而 Waterline 里,直接使用>/<即可
  • 多樣的操作支持 :提供了 26 種方法來進行增刪改查操作
  • 豐富的數據類型 :支持 JavaScipt 中除了對象外的所有數據類型,還額外提供了日期、時間、二進制、JSON的支持,數字還可以區分整數和浮點數

數據庫的支持情況

Waterline 里將操作數據庫的方法翻譯為具體的數據庫查詢語句的,叫適配器。分為兩大類:

  • 官方團隊提供的適配器:提供了對 MySQL / MongoDB / Redis 的支持
  • 第三方開發的適配器:提供了對 PostgreSQL / Oracle / SQL Server / OrientDB / ArangoDB / Apache Cassandra 的支持

基本上實現了對主流數據庫的支持。

配置中的適配器與連接

Waterline 之所以可以使用一樣的代碼來操作多種數據庫,奧妙

洗衣粉

在于其適配器。在進行配置的時候,需要設置兩方面的內容,一是具體使用哪些適配器,二是建立數據庫連接的時候,使用哪個適配器。下面是使用 MongoDB 的適配器創建一個數據庫連接的配置:

var mongoAdapter = require('sails-mongo');
var wlconfig = {
  adapters: {
    'default': mongoAdapter,
    'mongo': mongoAdapter
  },
  connections: {
    'mongo': {
      // adapters 中的適配器代碼
      adapter: 'mongo',
      url: 'mongodb://localhost/waterline-sample'
    }
  }
};

Waterline 在 MongoDB 的配置中,甚至還直接支持配置復制架構。

注意,需要在adapters中指定具體的適配器,connections中配置連接時再指定adapters中的適配器代碼。在進行具體的數據集合創建時,將會要指定使用connections中的哪個連接。

數據集合

Waterline 中負責具體與表和集合對應的是數據集合 Collection,它有點類似于 Mongoose 中的 Model,但在 Waterline 中,所有的數據集合合在一起,加上一些其它的屬性和方法,構成一整個models。

數據集合在初始化的時候,需要指定使用哪些連接,是否強制模式,具有哪些屬性以及集合的 id,如下:

var Post = Waterline.Collection.extend({
  // 集合的 id
  identity: 'post',
  // 使用的連接數
  connection: 'mongo',
  // 是否強制模式
  schema: true,
  attributes: {
    title: {
      type: 'string',
      required: true
    },
    content: 'string',
    createTime: 'date',
    lastModifyTime: 'date'
  }
});

配置相當簡單方便,類似于 Mongoose 中的 Schema。但要注意,指定屬性的字段時,使用的是一個字符串值,而不是 JavaScript 中的具體類型,目前支持的數據類型有string/text/integer/float/date/time/datetime/boolean/binary/array/json,這個范圍要比 JavaScript 的類型范圍大。

除了這四個基本配置,還可以配置校驗器,添加自定義的方法,設置生命周期回調方法等。

校驗器

balderdashy 為了 Sails.js 創建了 Waterline,為了實現 Waterline 中的數據校驗,又參與了 Anchor 的開發。

校驗器是在創建數據集合的時候指定給具體的屬性的,除了預定義的校驗器,還可以自定義校驗器。預定義的校驗器涵蓋了 Mongoose 中的必須字段驗證、字符串長度驗證等。比如下面這幾種:

// Waterline.Collection.extend() 的參數之一
attributes: {
  title: {
    type: 'string',
    required: true,
    maxLength: 100,
    minLength: 5
  },
  views: {
    type: 'integer',
    min: 0
  }
  createTime: {
    type: 'date',
    // 在某個時間點之前
    before: '2100-12-31',
    // 在某個時間點之后
    after: function(){
      return new Date();
    }
  }
}

除了上面這幾個簡單的, Anchor 支持的驗證器 還有針對時間、地理位置、正則表達式、布爾值、Email地址的,一共有 20 多個,用過 Mongoose 驗證器的人是不是已經淚流滿面了?

查詢

Waterline 提供了 26 種查詢方法 ——你沒有看錯,是 26 種。除了常規的find/create/update/destory方法,還有findLike/startWith/findByNameIn/nameContains之類。

查詢方法可以使用三種方式來調用,分別是:

  • 回調方式:直接把結果處理函數以回調函數的方法傳給查詢方法
  • 鏈式方式:查詢方法之后,直接以鏈式方式依次組織各個查詢接口
  • Promise:這一方式使得錯誤處理更漂亮,代碼也更容易閱讀

查詢的接口 也很豐富,where/sort/exec,還有 Mongoose 中的populate,查詢翻頁使用limit/skip,還提供了一個集成的方法paginate,直接傳入頁碼和每碼數量即可。

查詢的語法 就更豐富了,包括:

  • 條件修飾符 :包括>/</>=/<=/!/like/contains/startWith/endWith,大小比較的,除了常規的數字,也支持時間
  • 查詢選項 :提供了limit/skip兩個屬性組織分頁,使用sort屬性確定排序,排序即可以使用 SQL 語法里的DESC/ASC,也可以用對象的方式來直接指定排序標準,并支持指定多個排序標準。select指定查詢結果所包含的字段

生命周期回調

Mongoose 可以通過 中間件 ,來實現在進行特定操作的時候,調用自定義的方法。Waterline 必然也有這個功能,叫 生命周期回調(Lifecycle Callbacks) ,除了沒有 Mongoose 中的init,在create/update/destory時,均有多種回調。不過,調用的方法與 Mongoose 稍有不同,Waterline 的生命周期回調,是直接提供對應的方法名,分別是:

  • 創建時:beforeValidate/afterValidate/beforeCreate/afterCreate
  • 更新時:beforeValidate/afterValidate/beforeUpdate/afterUpdate
  • 刪除時:beforeDestroy/afterDestroy

這些方法,需要在初始化數據集合的時候進行定義。

還有嗎?

當然,Waterline 還支持 自定義數據類型索引集合間的關聯

下篇文章,我將使用一個例子來展示如何在實際的項目中使用 Waterline。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!