天天看點

JScript快速開發架構Edk:js2sql

我們已經對 ORM 的概念耳熟能詳了,而且使用動态語言一般都能比較輕松地寫一套 ORM 方案,網上比比皆是,有的參照 Ruby on Rail 的 ActiveRecord,有的參照 iBatis 的 SQLTemplate 模式,還有的采用微軟 Linq 的方案,無論哪一種思想和模式都力求把資料的增、删、改、查的操作映射(Mapping)為一套 API,用面向對象(Object-Oriented)的方式将這些對象組織起來,代替繁複的 SQL 來實作系統業務邏輯的過程,當然,最終仍要轉換到資料庫可以解析的 SQL 語句。“映射、業務對象、資料庫”這三者之間,映射負責業務邏輯到資料持久化的過程,并且可以想像映射居于業務對象與資料庫的“中間位置”。業務對象不但不會與資料庫直接打交道,而且其結果就是要讓業務對象與資料庫(資料庫)的分離。中間層的映射、如何映射于是顯得相當重要,直接影響到整體架構上的解耦。這裡又提到了 ORM 的一點好處:“解耦”。大多分離的目的便是為了解耦,看怎麼“解”。如果深入更多的 ORM 好處是什麼就讓大家去感受了,或者開發過程中大家都明白的,熟悉的,天天打交道的,本文則不想羅嗦複述。一言蔽之,當為稱道的地方乃解放了生産力——此說法可謂最适用不過。不過,看官會不會覺得行文至此寫得比較籠統?為表示筆者做了功課,還是貼一帖人家總結的現象,說明 ORM 帶來的好處:

目前大多數項目或産品都使用關系型資料庫實作業務資料的存儲,這樣在開發過程中,常常有一些業務邏輯需要直接用寫SQL語句實作,但這樣開發的結果是:遍地布滿SQL語句。這些高藕合的SQL語句給系統的改造和更新帶來很多無法預計的障礙。為了提高項目的靈活性,特别是快速開發,ORM是一個不錯的選擇。舉個簡單的例子:在使用ORM的系統中,當資料庫模型改變時,不再需要理會邏輯代碼和SQL語句中涉及到該模型的所有改動,隻需要将該模型映射的對象稍作改動,甚至不做改動就可以滿足要求。(1)

如果 NoSql、對象資料庫流行後,那麼則可能不需要存在映射層。目前的 ORM 實質可被認為是介乎關系模型和對象模型之間的一種混合協調機制。至于什麼“O/R 阻抗失衡(O/R Impedance Mismatch)”、“OO 資料庫”、“使用圖模型分析很多對象間複雜關系的設計合理性”,俺水準所限,不能也不可能深究,總之簡單的說,不直接寫 SQL 就對了。

我們知道雖然資料庫都支援标準 SQL 語句,但不同的資料庫之間還是會存着着不少差異,這導緻我們在操作不同的資料庫時不能統一 SQL 語句, 一旦更換了資料庫,那意味着 SQL 要重寫。為了避免災難性的後果,我們就需要對資料進行封裝。 封裝的意義就在于不管資料庫如何變化,我們都隻需要使用相同的代碼去擷取和建構我們需要的資料結構,而不用關心不同資料庫之間對于 SQL 的支援不同而造成的差異。

下面是我嘗試用 JS 寫的動态生成 SQL 類。

預備知識:ActiveRecord 模式

怎麼認識 ActiveRecord 模式呢?它是 ORM 方案中的一種,使得我們可以以對象的方式處理關系型資料庫為“行、列”為機關的處理方式。這裡不打算深入探讨背景的機制,就簡單地講一下基本認識。

在分析的時候,要定義不同對象之間的關系是非常自然的。比如說,在一個食譜資料庫中,一條食譜可能會有多條評論,多條評論又可能為同一作者所寫,而作者又可以創造多條食譜。透過定義這種連結到一起的關系可允許你通過更為直覺的、更強大的方式去操縱資料,——而這種方式,就是 ActiveRecord 的關系連結來支援。

首先是 belongTo 關聯。何謂“belongTo”,我們不妨這樣說(“屬于”這裡表示特定的關系):

公司資料庫中,賬單 accout 屬于 公司 company;

論壇程式中,文章 thread 屬于論壇 forum,也屬于分類 cateory;

一個畫冊中,縮略圖 thumbnail 屬于picture。

如果 bar 屬于foo,也就是說它們之間的關系 belongTo,那麼一般情況下,關系型資料庫實體表中,bar 表會有一稱作 foo_id 的字段,作為外鍵(foreign_key)出現。相對地,與 belongs_to 關聯相對應地就是 hasMany 關聯,也就是“多對一” v.s “一對多”之間的差別;

也許我們可以借助“父-子”的概念去了解,例如父母可有多個孩子,孩子隻有一對父母。賬單相當于公司是“子級别”,而公司相當于賬單是“父級别”。

目前可支援 belongTo(多對一)、hasMany(一對多)、多對多。而 hasOne 關系實際上包含在 belongTo 關系中。