ORM設計實際上是一個O到D的過程,就是由對象,最終產生資料實體.但是,問題在於傳統的設計我們必須設計一次業務對象,再重複設計一次關聯性物件(當然也可能是其他形式的儲存物件),這種方法實際上是兩張皮,而且這是一個重複的過程.但是由於現在尚未有物件導向的DBMS所以我們必須將O的設計按關聯式資料庫再實現成表.
想想看,我們平常設計一個對象,需要設計若干個屬性,每一個屬性,會有資料類型,資料長度,有效性規則等,而這些,在資料庫的實體裡是一一對應的,如果能實現設計一次就好了.於是,包括我在內的許多人,使用的是由D到O的設計方式,就是首先用DBMS提供的實體設計工具,設計出實體,然後再用C#去寫對應的對象.
這裡有兩個問題,第一是,這樣使我們的程式員不得不同時做DBA和程式員兩份工作,第二,業務對象和關係表結合的如此緊密,以致於當我們更換DBMS時,我們不得不再次重新設計關係實體或用其他工具實現轉換.最重要的是後續的工作,想想我都害怕,因為業務對象往往是隨時變化的,每一次變化,你不得不去修改大量的代碼,同時還要去保持關係資料表的同步變化,這不光是一個量大的工作,同時也是一個非常細緻,並且是繁瑣的工作.
不知道別人是怎麼處理的,不過,這種傳統的設計方法也有快速的解決方案,就是有人設計出業務對象後,然後利用諸如CodeSmith或其他的代碼產生工具,從關係表中匯出業務對象,同時產生其基本的CRUD操作.是的,我也這麼用過,它確實減輕了我不少的工作量,並且,CODESMITH是我見過的最棒的伸縮性最強,最易用的產生工具(不僅僅是代碼,任何可使用模板解決,甚至是合併列印,它都能輕鬆完成).可是,這隻是減輕了開發時的工作量,其後的擴充和維護工作,沒有任何工具能幫上我們的忙.另外,這種設計方法對於小項目確實不錯,如果可以的話,你還可以引入MS的ENTERPRISE LIBRARY中的資料存取快,進一步提高擴充性.但是,這種方式仍然是倒行逆施的.跟現在流行的物件導向設計方法是相違背的,很多人認為物件導向的設計方法加重了工作量,對於小的項目,確實如此,並且,對於小項目,我也不推薦使用物件導向設計,而且甚至我也不推薦分層的設計方法,原因無它,分層設計本來的目的不是加快開發速度,而是增加系統擴充性和靈活性.在小項目中使用三層結構和物件導向是得不償失的.所以,對於一般小項目,我也是將商務邏輯和資料存取兩層合并起來.所以,對於分層,當然是要看情況而定.而至於物件導向的設計方法,當然是無法復原擋的潮流,甚至DBMS也有一天會物件導向.為什麼呢?個人認為這是最為效法自然的方式.畢竟電腦以及其上的技術都是人類發明的,且是對人類現有知識的體現和拓展.其實物件導向這個東東是我們生活中最為常見的表現手法,例如你要去描寫一個人或一件物,你就會定義其屬性.
回到正題,那Nhibernate是什麼東東呢?你可以看看NHibernate的協助檔,其中有一個架構圖清晰的表示出NHibernate是業務對象與資料實體之間的橋樑.這個架構中稱NHibernate為Persist Object為持久對象.(持久這個詞翻譯的實在不怎麼樣,以前MS在VC裡叫它Serialize,稱續列化,反正這些詞是MS發明的).持久化對象的責任就是負責將對象永久儲存,而資料實體就是儲存後的形式,例如,橙子物件的一個執行個體Org,它的屬性如下:
顏色:黃色
重量:250g
等級:一級
.....
通過NHibernate你就可以將其儲存到資料庫的一個表:orange中,成為一個Record
而你需要做的是三件事:
1,定義一個類表示橙
2,寫一個讓NHibernate可以看得懂的設定檔,告訴它你使用何種DBMS,使用何種SQL語言,使用何種串連串跟資料來源串連.寫一個對應檔將你寫的橙這個業務類跟DBMS中的Orange表關聯起來
3,為橙這個對象寫出儲存,更新,刪除的方法即可.
聽起來不錯,業務對象和資料表好比一個事物的兩種表現形式,而NHibernate的作用就是把對象的表現形式轉換成資料表的表現形式,但是NHibernate也不是萬能的,所以,我們得寫對應檔告訴NHibernate如何去轉換(用過SQL的DTS的人都可以想想這個類似的過程吧)
那麼這樣我還不是的手工的去建這個Orange表嗎?NO,NO,如果Nhibernate不能產生資料表,那麼它就不是那麼完美的,但是,Nhibernate完全可以完成資料表的產生,修改和刪除,這部分功能在NHibernate.Tools.Hbm2DDL命名空間已經實現,也就是說NHibernate完全可以根據OR對應檔.hbm.xml來產生對應的資料表.而且,通過修改設定檔,還可以產生與對應DBMS相適應的資料表.
另外一點,如果使用Nhibernate,還有一個好外,舉個例子來說,有一天,突然,主管叫你說,橙子現在應市場部要求,要打上"原產地"這一項標籤,按我的經驗來說,這是經常的事,類似的事還有,規則的變更,比如,以前重量必須大於200g,現在要求必須大於250g,類似的規則我的變化(這在DBMS裡叫約束)
針對上述描述的情境,使用NHibernate實現的項目,你所要做的是為業務對象Org添加一個新屬性:原產地,並且為其Set屬性設定器作一個規則判斷,不合規則,則拋出異常並處理.同時,為該對象的對應檔.hbm.xml添加一個新的Property映射,最後,在具體使用該對象的地方為"原產體"屬性加入賦值即可.一切OK
但是,假如你不是用ORM的方式去設計,而是像我以前那樣將業務對象和資料實體分開設計,然後寫自己的業務對象操作類來完成對資料實體的操作(這是很常見的,像MS的PETSHOP就是,這種方式也有面象服務和面象對象之分,區別在於,面向服務是定義一個擁有靜態方法的類,將要操作的對象屬性做為參數傳入,而物件導向的方法,則需要寫一個業務對象,並為其定義屬性,然後在其中定義方法以實現CRUD.兩個方法各有千秋,前一種方法,無需執行個體化對象,因為基本上沒有業務對象,只是將業務對象的"屬性"做參數傳入並處理,因此,節省資源.但是,後一種方法更靈活),無論如何,這種情況下,你要完成這種業務對象或規則的變更,都是一件需要極其小心的事,因為你可能要做以下操作:
1,修改資料表以使其符合新的業務對象
2,修改業務對象(如果使用物件導向而不是服務)
3,修改參數(如果使用面向服務,則需要添加或移除各個靜態方法傳入的參數)
你必須保證每一處小的改動都在業務對象和資料實體間保持完全一致,否則,小小的錯誤就可能導致問題出現
跟前面的分層設計和物件導向一樣,ORM從一出現到現在,也是面臨種種爭執,不過,這完全是正常的,因為,大家看問題的角度和層面不一樣,而且大家的需求也不盡一致,所以,無需懷疑ORM的必要性,對有用的人來說,它就是寶貝和武器,對於暫時不需要它的人來說,它可能是雞肋.不過,至少從我的體會來說,我覺得它真的解決了我的困擾,這才是最重要的
另外,說明一下,ORM不等於NHibernate,只不過,NHibernate名氣太大了,以致於一提起ORM,人們就想起它,其實它不是新鮮的東西,它是JAVA下的Hibernate架構移植到.NET上的實現,實際上,有很多人也寫過ORM架構,有些是輕量級的,像Smart Persist Layer等,只不過,與Nhibernate比起來,仍相去甚遠罷了.另外,閑話一句,一直以來,JAVA和.NET兩大陣營都互相鄙視,我覺得實屬不該,因為Nhibernate就是一個很好的例子.互相吸收這才最重要.Java的長處正是.NET的不足,.NET的優勢保嘗不是.NET的短處呢?以前很多JAVA們,笑話.NET程式員,有一個很重要的原因就是像有些老鳥網友說的那樣:JAVA下的各種架構隨手拈來都是威力無經,像Hibernate,像Spring,可是,.NET就太少這方面的東西,MS划了個美好的藍圖,可是藍力上的建築太少了,因此,還需要向JAVA學習借鑒.就算如Nhibernate般移植過來,也不失為一種進步.
同時也要說明一下的是NHibernate不是一個軟體,很多人誤會,以為它是一個類似MyGenerator似的代碼產生工具,其實不是,它是一個持久化架構.很多初學者聽到架構會犯暈,架構就是為解決某種問題,或某個情境而提出的解決方案,你可以這樣理解它,能稱的上框加的,一定是完整的解決了某一方面的事務.當然,也有輕量級和重量級之分了.
因此,一個完整的使用NHibernate的項目,實際上可以分成以下幾部分:
NHibernate
業務對象
業務對象映射配置
其他業務操作類
NHibernate配置
資料實體
而Nhibernate的原理就是讀取設定檔,串連到對應的資料庫,根據業務對象以及業務對象映射配置,將業務對象轉換成資料實體並儲存
需要說明的是:
1,資料來源(就是資料實體的管理者)是可配置的,目前NHIBERNATE支援ORACLE,SQL SERVER,MYSQL SERVER,FIREBIRD等,算是十分強大了吧
2,不是說用了NHIBERNATE就拋棄了ADO.NET等,NHibernate仍然支援你使用它們來訪問實體物件