天天看點

O/R Mapping 基本概念

(本文引自:http://www.cnblogs.com/idior/archive/2005/07/04/186086.html)

近日 有關o/r m的讨論突然多了起來. 在這裡覺得有必要澄清一些概念, 免的大家讨論來讨論去, 才發現最根本的了解有問題.本文并不保證所有觀點正确, 隻是個人在某一特定時期的了解.

1. 何謂Entity?

實體(類似于j2ee中的Entity Bean)通常指一個承載資料的對象, 但是注意它也是可以有行為的! 隻不過它的行為一般隻操作自身的資料. 比如下面這個例子:

O/R Mapping 基本概念

class  Person

O/R Mapping 基本概念
O/R Mapping 基本概念
O/R Mapping 基本概念

{

O/R Mapping 基本概念

  string firstName;

O/R Mapping 基本概念

  string lastName;

O/R Mapping 基本概念
O/R Mapping 基本概念

  public void GetName()

O/R Mapping 基本概念
O/R Mapping 基本概念
O/R Mapping 基本概念

{

O/R Mapping 基本概念

     return  lastName+firstName;

O/R Mapping 基本概念

  }   

O/R Mapping 基本概念

}

O/R Mapping 基本概念

GetName就是它的一個行為.

2 何謂Domain Object?

對象最重要的特性在于它擁有行為. 僅僅擁有資料,你可以稱它為對象, 但是它卻失去它最重要的靈魂.

O/R Mapping 基本概念

class  Person

O/R Mapping 基本概念
O/R Mapping 基本概念
O/R Mapping 基本概念

{

O/R Mapping 基本概念

  string firstName;

O/R Mapping 基本概念

  string lastName;

O/R Mapping 基本概念

  Role role;

O/R Mapping 基本概念

  int baseWage;

O/R Mapping 基本概念

  public void GetSalary()

O/R Mapping 基本概念
O/R Mapping 基本概念
O/R Mapping 基本概念

{

O/R Mapping 基本概念

     return baseWage*role.GetFactory();

O/R Mapping 基本概念

  }   

O/R Mapping 基本概念

}

這樣需要和别的對象(不是Value Object)打交道的對象,我就不再稱其為實體. 領域模型就是指由這些具有業務邏輯的對象構成的模型.

3. E/R M or O/R M?!!

仔細想想我們為什麼需要o/r m,無非是想利用oo的多态來處理複雜的業務邏輯, 而不是靠一堆的if else.

而現在在很多人的手上o/r m全變成了e/r m.他們不考慮對象的行為, 而全關注于如何儲存資料.這樣也難怪他們會産生将CRUD這些操作放入對象中的念頭. 如果你不能深刻了解oo, 那麼我不推薦你使用o/r m, Table Gateway, Row Gateway才是你想要的東西.

作為一個O/R M架構,很重要的一點就是實作映射的透明性(Transparent),比較顯著的特點就是在代碼中我們是看不到SQL語句的(架構自動生成了),但是這并不是透明性的實質,詳見Enterprise Persistence Design,這裡所指的O/R M就是類似于此的架構.

4. POEAA中的相關概念

  很多次發現有人錯用其中的概念, 這裡順便總結一下:

  1. Table Gateway

    以表為機關的實體,基本沒有行為,隻有CRUD操作.

  2. Row Gateway

    以行為機關的實體,基本沒有行為,隻有CRUD操作.

  3. Active Record

    以行為機關的實體,擁有一些基本的操作自身資料的行為(如上例中的GetName),同時包含有CRUD操作.

其實Active Record最符合某些簡單的需求, 接近于E/R m.

通常也有很多人把它當作O/R m.不過需要注意的是Active Record中是充滿了SQL語句的(不像orm的SQL透明), 是以有人想起來利用O/R m來實作"Active Record", 雖然在他們眼裡看起來很友善, 其實根本就是返祖.

用CodeGenerator來實作Active Record也許是一個比較好的方法.

  4. Data Mapper

這才是真正的O/R m,Hibernate等等工具的目标.

5.O/R M需要關注的地方 (希望大家幫忙完善一下)

 1. 關聯以及與此相關的Lazy Load, O/R M是如何管理類之間的關聯.當然這不僅于O/R M有關與設計者的設計水準也有很大關系.

 2. O/R M對繼承關系的處理.

 3. O/R M對事務的支援.

 4. O/R M對查詢的支援.

以上觀點僅屬個人意見, 不過在大家讨論有關O/R M之前, 希望先就一些基本概念達成共識, 不然讨論下去會越離越遠.

(建議: 如果對oo以及dp沒有一定程度的了解, 最好别使用o/r m, dataset 加上codesmith或許是更好的選擇)

Feedback

# re: O/R m 基本概念(歡迎指正)  回複   

2005-07-04 16:27 by Cavingdeep 不錯,了解到要點了!^_^

# re: O/R m 基本概念(歡迎指正)  回複   

2005-07-04 16:31 by James good,講得很簡練而明白.

# re: O/R m 基本概念(歡迎指正)  回複   

2005-07-04 16:47 by neuhawk 看了幾個.net開源的orm,總感覺不理想。

不是沒有釋出穩定版本,就是有些功能太弱,如查詢、1:N、

N:M!

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-04 16:53 by 程式人生 探讨!

我的觀點:

假設有鈔票,商店,一種設計是

鈔票.使用(商店);

一種是:

商店.銷售(鈔票);

在這裡我認為鈔票是實體類,商店是操作類;

如果第一種設計在過了一個食堂的時候,那麼就勢必影響鈔票的行為:

鈔票.使用(食堂);

隻有食堂和商店使用相同的接口,才能讓鈔票不必為後來的需求做修改,但這樣對以前的開發水準将有較高的要求。

如果使用後一種設計,那麼:

食堂.銷售飯(鈔票);

這個後來的需求建立在已有的設計“鈔票”,是以不會影響以前的設計。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-04 17:59 by tubo 其實前面已經說得很清楚了,鈔票自身還是可能有行為的(比如,兌換成美元),我想你不會去食堂兌換成美元吧

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-04 18:01 by cookey 程式人生 的探讨話題和設計模式有關吧,好象和orm關系不大.

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-04 18:11 by 蛙蛙池塘 ORM的模型我就看過《asp.net電子商務進階程式設計》裡面用的那個CMP(托管容器持久性)的架構,是仿照J2EE來做的,大家有空也不妨研究一下,就有幾個類來做的,我感覺可用性還是可以的。也是每個持久對象可以執行CRUD,然後在資料服務層來封裝一下底層的業務邏輯

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-04 18:13 by idior 程式人生的問題涉及到責任配置設定的問題。

另外目前有兩種設計思路:

1。 将行為賦予包含待資料的對象本身

2。 XXX對象僅包涵資料, 通過另一個XXXmanager來操作該對象。

第二種在soa中比較常見, 不過以上都不是本文主要讨論的問題, 希望大家的評論集中對orm的了解上上, 以上問題可以由誰再寫一篇文章讨論。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 09:27 by tdd No,不贊同。

Table Gateway、Row Gateway、Active Record、Data Mapper均是對象關系映射的實作模式,真正的對象關系映射目前是不存在的,所有的O/R Mapping方案都隻不過是一個虛假的過渡品而已。嚴格來說,凡是能建立關系與對象之關的映射的,無論能力強弱,都可稱之為O/R Mapping方案.

所謂的Hibernate也隻是衆多O/R Mapping解決方案相較更為廣泛使用的一種政策,它本身并不能說明什麼才是真的O/R。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 09:36 by 蛙蛙池塘 轉貼:【Uestc95的空間站 - 火星就是地球的未來?...

】 http://blog.joycode.com/uestc95/archive/2003/11/04/5176.aspx

O/R Mapping,陷阱還是蘋果?

在JAVA的世界始終在讨論的一個問題是:EJB是否欺騙了我們?當然這樣的問題就好像雞生蛋蛋生雞一樣沒有定論和結果,但是不容置疑的是EJB的确不是當初我們想像的那樣好,世界上本來就沒有救世主,一切還都要靠自己。而在.NET世界則更是如此,都說微軟提供了開發人員所需要的一切,進而使得開發人員越來越貶值,但實際情況卻恰恰相反,太多的東西他都沒有提供,比如O/R Mapping機制,持久維護機制等等。

使用MS提供的免費午餐帶來的代價就是:你别無選擇,因為你也根本沒有其他的選擇,比如COM+,Remoting,再比如以後的Indigo。從另外一個角度來講,這也未嘗不是一件好事情,當然前提你沒有發現JAVA世界的精彩。

上面的話其實沒有開始這篇随筆的主題:O/R Mapping,陷阱還是蘋果?隻是開始的一瞬間,思維胡亂跳躍。其實還有一個更大的延伸話題是:OO世界是否是一個虛幻的世界?當然這就不是我所能探讨的話題了,你可以和OO大師們一論高低,

.NET 2.0将會提供O/R Mapping機制的實作,你自己看看就會發現他隻是在和J2EE相靠攏,當然J2EE的O/R Mapping也是在向某種東西靠攏,究竟是什麼呢?你當然會說是:高效開發,提升可延展性,降低需求變化給軟體設計和編碼帶來的振蕩。沒錯,的确是這樣的。但是這樣作并不是沒有任何犧牲的,那就是增加編碼的複雜度和工作量,畢竟宇宙間能量是守恒的! 是蘋果還是陷阱,就要看這些犧牲是否值得了。這就不是一個是或者否能精确回答的問題了,通過精确的項目控制和人為能力,完全可以做到高效率,而不采用O/R Mapping,比如前提是不考慮多資料庫支援。因為說到底,O/R Mapping機制提供的可延展性是非常有限的,他對于業務邏輯的支援基本上等于0,而我們大量的工作量都在業務邏輯部分。這也是我為什麼有這樣一個随筆的原因所在。我們在仔細分析了目前業務環境之後就要決定O/R Mapping是否值得去使用,如果你追求的高效率,而不是所謂的“優美設計”,那麼就放棄吧。

比如我們高強度的ERP運算的時候,一定需要繞開O/R Mapping機制,否則等待我們的一定會是系統當機。而現在我發現越來越多的開發人員在刻意追求所謂的OO設計,尤其是.NET世界,雖然O/R Mapping算不上“過度設計”,但是本質一樣。所有提供O/R Mapping機制的技術都會提供對象緩存技術,為什麼?因為他知道這種建構實體和進行持久化的動作将會是非常耗費系統資源的,也就是說他們了解O/R Mapping所帶來的問題,通過對象緩存技術來盡量抵消這個缺陷,但僅僅是“盡量”,是以我們開發或者分析設計人員更要明白的了解何時該繞過O/R Mapping!

不是說你運用OO技術和設計模式多麼熟練就表明你的功力有多高,而是說做到正确辨識何時該用什麼才是真正的高手。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 09:41 by 小殘 這篇轉貼講得好

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 09:51 by 雙魚座 哦,E/R Mapping是什麼東東?

不能接受這樣的評述:

仔細想想我們為什麼需要o/r m,無非是想利用oo的多态來處理複雜的業務邏輯, 而不是靠一堆的if else.

而現在在很多人的手上o/r m全變成了e/r m.他們不考慮對象的行為, 而全關注于如何儲存資料.這樣也難怪他們會産生将CRUD這些操作放入對象中的念頭. 如果你不能深刻了解oo, 那麼我不推薦你使用o/r m, Table Gateway, Row Gateway才是你想要的東西.

其實單純為了O/R Mapping而O/R Mapping毫無意義。在完整的開發周期中,前面需要領域模型(ER模型或者UML模型,兩者隻是關注點不一樣),後面有對業務層甚至表現層對O&R的消費。O/R Mapping有時候其實就是在面向對象與運作環境的中繼資料層的妥協而已。在某些特定情況下,對象這此僅僅隻是一個資料容器并沒有異化面向對象的本質。

直接通過模型來生成領域對象代碼是為了提高開發的生産力。但是從模型中生成的代碼往往都是“死對象”,都不包括行為。因為來自模型嘛。僅僅将這些對象作為資料容器或者關系容器也就足夠了。

實體的行為,可以通過另外的對象來補充之。事實上,在實際開發中,單純某個實體内部的行為少之又少,多态就更不需要了。

我對以上概念的了解:

對象:對于領域是抽象的,對于實體又是具體的概念

實體:一個中繼資料級别的概念,業務對象的描述器而已

關系:另外一個中繼資料級别的概念,聚合,合成,繼承,關聯,自引用,大概這麼五種吧。你所謂的Table Gateway, Row Gateway是無法描述複雜關系的。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 09:57 by 雙魚座 >>不是說你運用OO技術和設計模式多麼熟練就表明你的功力有多高,而是說做到正确辨識何時該用什麼才是真正的高手。

經典!

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 11:03 by 冰火 基本上贊同idior的了解。

但有兩點談談我的看法:

1、對ActiveRecord的了解不同意。

ActiveRecord本質上應該是領域模型,并不是實體+資料通路。

ActiveRecord可以包含幾乎所有的領域邏輯,也可能隻是一些面向資料的普通代碼。

ActiveRecord通常是和資料庫表同構的。一個包含了資料通路的領域模型。因為他們是同構的,資料映射不太複雜,是以不必要用到分離的Mapper。

2、ORM需要關注的可能還有:辨別,延遲加載,查詢。

個人觀點,歡迎讨論!

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 11:38 by [email protected] "不是說你運用OO技術和設計模式多麼熟練就表明你的功力有多高,而是說做到正确辨識何時該用什麼才是真正的高手"----這句話真經典。很多人都變得為了技術而技術了,唉

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-05 12:36 by 寒楓天傷 不同意關于ActiveRecord的評述。

另外,多不多态,這是一個值得探讨的問題,有一些大師級指出多态是一種沒事找事幹的行為,純屬瞎折騰(不過,我覺得還是很有用的)。另外還包括繼承之類的OO概念...也是非常值得争議的。目前就OO而言,也不是很令人滿意,有理論背景因素,也有實踐因素,還有目前科學技術水準的制約。O/R目前實際上有空中樓閣之嫌,所有的東西都不如我們一開始認為的那樣好...還有待發展呐

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-09 04:21 by workjie 不為了技術而技術,不這樣走過一段路,你能了解什麼?

誰都是這樣過來的!

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-16 16:59 by happyprogram 學習。

workjie:關鍵是有沒有懸崖勒馬,呵呵

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-07-18 16:51 by 菩提樹 發現各位口中的名詞真多,我基本上是應接不暇了

看來各位的概念是已經背的滾瓜爛熟了,慚愧,慚愧

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-10 22:58 by 生活、工作 Domain Object每個項目都是不同的,其所擁有的方法是由業務決定的,很難自動化。

現在都說三層,表現層、業務層、資料通路層,這裡不說表現層。我這裡有三個類:OrderInfo、OrderDataServices、Order。其中,OrderInfo對應于這裡描述的Entity,這個是可以自動化的(比如用CodeSmith生成),OrderDataServices在資料通路層,執行CRUD和其他一些通路資料庫的操作,我估計隻能部分自動化,難以達到100%自動化,如果根據業務邏輯,先寫好部分存儲過程,可能自動化程度會高一點(我這裡所說的并不是将業務邏輯寫進存儲過程,而是将業務邏輯中最基礎的一些資料操作寫進存儲過程),Order在業務層,就更難自動化了,當然可以少部分自動化。

再舉個例子,UserInfo、UserDataServices、User,UserDataServices裡除了有CRUD操作外,還有個GetPassword()方法,這個顯然是根據業務邏輯而确定的,User類裡有個Authentication()方法,資料庫裡肯定沒有相關資訊,來給這個User類自動生成Authentication()方法。

ORM就字面來看,是說對象與對象之間的關系,好像與資料沒有很大聯系,但我們在說ORM時卻往往根資料庫聯系在一起,不知其最初是不是從資料而來的。

我水準有限,項目經驗也很少,不知說的對不對。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-11 11:23 by idior @生活、工作

ORM是對象-關系資料庫映射的意思. 不是對象關系映射.

因為現在的程式設計模型多是oo模型,而資料庫用的又都是關系型資料庫, 是以才有了ORM的概念.

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-11 12:45 by 生活、工作 謝謝,知道了這裡的關系是指關系資料庫。

不過因為昨天有點事,我的回複還沒寫完,今天繼續。

如果僅根據資料庫,一般XXXXInfo、XXXXDataServices是可以生成的,但處于業務邏輯層的User類,還需要大量的業務資訊(如來源于UML的資訊)才能自動生成,那麼應該如何做呢?一般都是将業務邏輯層類所需要的方法放到配置檔案裡,有ORM工具從配置檔案中讀取業務資訊,進而生成業務邏輯層的類。這裡對象與對象之間的關系就展現在配置檔案中。

我感覺如果僅僅生成類似XXXXInfo、XXXXDataServices類,用CodeSmith就不錯。如果也要生成Biz類,看來要用ORM工具了。

不知我的了解對不對,請指教。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-11 17:51 by idior @生活、工作

1。 o/r m不是代碼生成器。

2。 o/r m關注于持久層的操作, 業務邏輯與之無關。它不會自動生成業務代碼。

3。 o/r m的目的在于讓你關注業務邏輯的編寫,而較少的考慮資料儲存。

你的了解似乎有點偏差。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-11 22:18 by 生活、工作 呵呵,謝謝idior ,是我搞錯了,我的原本意思是這樣的:

如果僅根據資料庫,一般XXXXInfo是可以生成的,但處于資料通路層的XXXXDataServices類隻能部分生成,還需要大量的業務資訊(如來源于UML的資訊)才能自動生成,那麼應該如何做呢?一般都是将業務邏輯層類所要用到的、XXXXDataServices類的方法描述,放到配置檔案裡,由ORM工具從配置檔案中讀取這些資訊,進而生成資料通路層的類。

請看看對不對?

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-12 11:20 by idior XXXXDataServices中的方法基本上就是CRUD,似乎不需要描述, 配置檔案中的資訊一般用于指導如何映射.

參考一下這個吧.

http://www.alphatom.com/content/view/267/69/

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-08-12 21:35 by 生活、工作 "XXXXDataServices中的方法基本上就是CRUD",但我覺得還不夠,特别是R和U.

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2005-09-07 11:16 by yyanghhong 大多數系統有domain object, Data access object 和service layer就足夠了, 用hibernate可以實作domain object和Data access object, 它并沒有涉及service layer,

spring是把service和domain object, Data access object連在一起的好架構, 比如用他來配置service裡的transaction.

有人說DTO是用來實作傳遞資料在remote layer之間, 其實是多此一舉, hibernate裡可把domain object轉為detched object來達到這個目的, 用web service的話也可用xml attribute來serialize domain object.

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2006-02-01 20:53 by Niwalker ORM的思考:

大多人做OO總是喜歡鑽牛角尖,許多人認為關系資料庫的實體模型不是OO模型,這一點來說無疑是正确的,對于域模型來說,域對象和資料庫中的實體對象不完全是一一對應的,于是有了各種各樣的映射模型出現。但是他們忽略了一個事實,那就是在OO世界中任何東西都可以表示為對象,資料庫也不例外,資料庫是對象,資料庫中的表同樣也是,況且很多業務更接近資料庫的關系模型,如日常中的報表之類(面向對象資料庫系統之是以不能廣泛流行的原因恐怕這也是其中之一吧?)。

當我們換一種角度來重新審視資料庫的時候,也就是說當你把資料庫看作一個對象的時候,那麼對象之間的關系是否會更清晰些?

日前看了DLinq(C#3.0)項目的實作,個人覺得MS的思路是正确的,這也是DLinq值得期待的一個理由。如果DLinq正是釋出之時,我想上面的讨論大多數都顯得很多餘。另外,注意一個事實,那就是DLinq并不隻是ORM。

# re: O/R Mapping 基本概念(歡迎指正)  回複   

2006-03-04 11:31 by ^_^ @Niwalker

使用orm就是一種把資料庫看成對象的方式吧。畢竟資料庫本身提供的接口不是面向對象的。orm就是一種跨系統邊界的包裝?