ORM是是非非

簡單講,開發的時候方便了(敏捷開發?),運行的時候慢了,而且,不能深入細節

一些參考吧

回答ruby面試三 用的

 

某人 寫道
Advantages:

Speeds-up Development - eliminates the need for repetitive SQL code.
Reduces Development Time.
Reduces Development Costs.
Overcomes vendor specific SQL differences - the ORM knows how to write vendor specific SQL so you don't have to.

Disadvantages:

Loss in developer productivity whilst they learn to program with ORM.
Developers loose understanding of what the code is actually doing - the developer is more in control using SQL.
ORM has a tendency to be slow.
ORM fail to compete against SQL queries for complex queries.

 

 

寫道
面向對象有它的本質要求。如果你的編程僅僅是“基於對象”而不是“面向對象”的,雖然你也能收到一些“代碼封裝成類型”的好處,但是你其實很難用到真正深入的面向對象軟件工程設計技術。 

面向對象ORM非常重要,堪稱面向對象軟件工程技術的核心。但是,有很多ORM只是“基於對象”的,不是“面向對象”的。面向對象的ORM應該與面向對象的軟件工程技術一樣,首要問題是:解決基於對象的結構化技術(如今所有頑固堅持結構化技術的人都使用OOPL語言來說明自己的理論,因此OOPL不等代表OO的水平)與基於多態的面向對象技術的“阻抗不匹配”現象。 

套用面向對象技術的本質特種,面向對象ORM應該有以下本質特徵(下面是用了熟悉的c#的術語): 

1. 自動維護類型定義。我們把一個對象“丟給”面向對象ORM,它就應該自動分析對象的Field、Property。如果在使用一段時間之後我們的對象類型定義改變了,原來的數據應該仍然能夠回覆爲新的類型的對象,只不過有些新增字段成爲默認值。例如: 

User u=null; 
//todo: 產生u實例 
using(var db=Domain(數據庫連接)) 

db.Save(u); 
db.Commit(); 

db事先並不知道“User”這個類型,它應該“臨時”反射User類型並記錄下來。那些要求我們依據關係數據庫的數據字典來寫class代碼的想法可謂“居心叵測”。 

2. 標識唯一性。至少在同一個進程中(也就是在同一個ORM環境中)兩個不同的查詢,如果邏輯上應該有相同的對象返回,那麼ORM就應該體現這個規則。例如有一個過程是“保存工單記錄”,工單中有字段記錄負責評估工單的產品經理,另外有一個過程是“查詢某個項目組的產品經理”。看上去這兩個過程沒有緊密的邏輯聯繫,但是他們有數據聯繫。如果一個地方建立個一個產品經理對象並調用了第一個方法,另一個地方隨後調用了第二個方法,那麼對於同一個產品經理,第二個方法不應重新建立新的內存對象,而應該返回第一個方法所使用的那個對象(除非調用第二個方法時第一個方法使用的那個對象已經被GC釋放了)。 

顯然,你的ORM應該有自己的緩存機制來維護對各個對象的弱引用。緩存並不是僅用來提高查詢速度的,還有邏輯意義上的用處。 

3. 繼承性。如果上述例子中的變量u被實例化爲一個從User類繼承的“系統管理員”類,數據庫當然應該可以保存,並且在隨後“查詢系統管理員”操作中可以正確返回系統管理員的全部字段。顯然,子類和父類在數據庫中肯定要分開成不同的類型(或者叫做“表”)。 

例如假設Domain數據庫類型的Query <T>返回所有T類型對象的一個QueryProvider(Linq定義的): 
User u=null; 
u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。 
using(var db=Domain(數據庫連接)) 

db.Save(u); 
db.Commit(); 
var result=(from u in db.Query <系統管理員> where u.姓名=="大寶" select u).FirstOrDefault();
//todo: result.Print(); 


4. 多態性。 

User u=null; 
u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。 
using(var db=Domain(數據庫連接)) 

db.Save(u); 
db.Commit(); 
var result=(from u in db.Query <User> where u.姓名=="大寶" select u).FirstOrDefault(); 
//todo: result.Print(); 

注意result的定義類型是User而不是“系統管理員”。多態讓我們寫出“引擎式”的代碼,這個引擎拖動的車子是虛構的、通用的。ORM應該支持OO的這個本質要求。 

5. 網狀關聯。ORM應該隱藏面向對象數據庫與關係數據庫在處理關聯方面的差別。 

假設User中有一個“配偶”字段,並且有一個“情人”集合,查詢“系統管理員的配偶和情人”方法可能這樣寫: 

User u=null; 
u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。 
//todo: u.配偶=...... 
using(var db=Domain(數據庫連接)) 

db.Save(u); 
db.Commit() 
var result1=from u in db.Query <系統管理員> select u.配偶; 
//todo: result1.ForEach(p=>{p.Print();}); 
var result2=(from u in db.Query <系統管理員> select u).SelectMany(u=>u.情人); 
//todo: result2.ForEach(q=>{q.Print();}); 

如果你使用面向對象數據庫,那麼從User到它的配偶之間以及每一位情人之間的存儲關聯是“一步到位”的,而不是像關係數據庫那樣需要使用inner join。因此,面向對象昂數據庫(理論上)應該比關係數據庫速度快至少10倍。 

不應該強迫對象類型之間關係模仿關係數據庫的“外鍵”來建立,應該使用上面的自然、OOPL原始的形態。這樣,如果你的ORM的底層是關係數據庫,例如是SQL Server,那麼你的QueryProvider(Linq)實現就不得不將關係翻譯爲關聯操作。 

6. 延遲加載。顯然,當我們查詢一堆User出來之後,它的“七姑八姨”等關係對象不需要加載到內存裏(否則這個加載操作就太可怕了),但是當我們訪問關聯對象時應該自動從數據庫中加載到內存。對於引用單個對象和引用集合對象都是應該這樣的。 

7. 級聯更新。如果我們實例化一個User類型對象,並且給它的“配偶”賦值,那麼在保存這個User類型對象的時候就應該自動保存(新增或者更新都叫是保存操作)它的配偶,而不需要我們在程序中去寫保存配偶的代碼。如果我們查詢出一個User,他有很多情人,我們用程序向他的“情人集合”裏插入一個情人或者刪除一個情人,然後保存他,那麼ORM應該自動也去保存這個情人或者刪除它與這個情人的數據庫內連接,但是不需要重複保存那些沒有動過的情人對象。 

<完>
http://topic.csdn.net/u/20080227/12/aeeec383-2def-48b9-8bab-336926f1d33b.html

對我有用[0]
丟個板磚[0]
引用
舉報
管理
TOP

zzxap用戶頭像
zzxap
(風語者)
等 級:

2


#2樓 得分:0回覆於:2009-11-04 12:07:20
例如我們需要開發一個“註冊用戶”工程,這個工程顯然要給將來各個應用系統共享,也就是說將來的各個系統依賴於它。這個系統中定義了用戶類,保存了用戶對象。那麼當用戶被刪除,或者其某些屬性修改了,我們要通知其它子系統,怎麼辦呢?調用其它子系統的功能嗎?有設計知識的架構師不會這樣輕易回答,因爲前面已經說了各個系統依賴於它,而不是它依賴於在它之後纔開發的子系統。這就需要各個子系統能夠註冊事件處理程序到用戶對象類中。但是這看起來有點麻煩,就是以往在使用事件時我們通常都是將事件處理程序註冊到一個對象上,而這裏我們是開發ORM,我們希望處理程序針對“一類”對象均自動註冊,這兩者的編程方法有區別。 


我們的ORM是一個完整的面向對象風格的數據庫工具,它不可能依賴於底層關係數據庫來實現一個純粹工作在應用程序中的觸發器,必須依靠自身力量解決。 


不要告訴我“這就是AOP”就完了(當您並不能直接拿出一個成熟的AOP代碼給我直接使用在此係統上時),因爲我接下來要描述處理這個過程的設計規格,所以我其實並不管我的做法是不是AOP,我在此只是這樣實現這個系統的: 

public static class RegisterCallbacks 

public static void RegisterCallbackAfterCreate(Type type, CallbackHandler handler); 
public static void RegisterCallbackAfterDelete(Type type, CallbackHandler handler); 
public static void RegisterCallbackAfterUpdate(Type type, CallbackHandler handler); 

public static void Created(IDomainClient sender, object obj); 
public static void Deleted(IDomainClient sender, object obj); 
public static void Updated(IDomainClient sender, object obj); 



這個類是一個static類,它是ORM的一個獨立的信息管理類,它記錄了各個類型的數據當在數據庫中更新(Create、Update、Delete)時應該觸發哪些方法(handlers)。顯然,同一類型同一更新方法可以註冊多個handler。而handler的類型定義如下: 

public delegate void CallbackHandler(IDomainClient sender, CallbackArgs args); 

public class CallbackArgs : EventArgs 

public object Obj; 



IDomainClient 是我定義的數據庫打開之後的操作接口(提供了事務功能),其設計規格解釋可以參考我開頭提到的那篇帖子。 

假設一個“發送歡迎短信任務安排”的類需要被“用戶”這個類所觸發,也就是說一旦一個用戶被新增入系統數據庫就要觸發給他發送一個歡迎短信的任務記錄,那麼我們(通常在發送歡迎短信任務安排這個類中,當然也可以寫在其它代碼文檔中)應該可以見到這樣的代碼: 

[RegisterCallbacks] 
public static void Register() 

RegisterCallbacks.RegisterCallbackAfterCreate(typeof(用戶), 準備發送歡迎短信); 


private static void 準備發送歡迎短信(IDomainClient db, CallbackArgs args) 

var obj = args.Obj as 用戶; 
db.Save(new 發送歡迎短信任務安排{ 用戶=obj, 開始時間=DateTime.Now, 過期時間=DateTime.Now.AddHours(1) }); 


這個代碼告訴 RegisterCallbacks 這個管理類,當“用戶”類型的對象被數據庫創建時要觸發“準備發送歡迎短信”這個方法。 


在 RegisterCallbacks 中並不關聯具體的數據庫。一旦通過某一個數據庫對象實例新增了一個對象,這個數據庫對象就會去調用靜態方法 

RegisterCallbacks.Created(thisDb,theObject) 

這樣 RegisterCallbacks 就會幫助數據庫調用 theObject 的所有類型(包括各層父類、接口)在 Create 操作上所需要的觸發方法。這樣,各個在ORM之後開發的領域對象工程,以及各種不同的數據庫實現,可以在ORM幫助下實現觸發器功能。 


對於Update、Delete操作,其機制完全與Create操作一致。 


我們使用關係數據庫的經驗可以告訴我們,觸發器所修改的數據是可以回滾的。因此,這個“準備發送歡迎短信”中無需寫 
     
    db.Commit() 

因爲如果 

Save(用戶); 

觸發它,緊接下來會被 Rollback 命令回滾,那麼觸發器中的更新當然也應該回滾。同樣,如果調用方 Commit,這時候這個新增發送歡迎短信安排記錄纔算真正保存到數據庫文件中。在這個觸發器程序執行過程中,可以從 db 查詢到所有調用方的代碼已經更新到數據庫但是還沒有 Commit 的數據,儘管這些數據可能隨後被 Rollback。說白了,觸發器是在一個事務中對象被更新到數據庫但是還沒有進行 Commit 或者 Rollback 時觸發的。 


但是,我們什麼時候去調用 Register 方法呢?是在領域類型的.cctor中嗎?顯然,這時候有點晚,因爲.cctor只有在類型第一次被真正用來實例化對象時才執行。如果我們啓動一個應用系統,新增了一個用戶,此時還沒有使用過發送歡迎短信任務安排對象,我們就無法讓這個觸發器被註冊到 RegisterCallbacks 中。 


爲了解決這個問題,我首先定義了一個標籤 

[AttributeUsage(AttributeTargets.Method, AllowMultiple=false, Inherited=false)] 
public class RegisterCallbacksAttribute : Attribute 



這個標籤用於註明類型中上述Register靜態方法。當數據庫對象第一次實例化時,它應該去遍歷當前應用程序域中所有的引用了這個ORM工程的assembly中的每一個類型,從類型中找出具有 RegisterCallbacksAttribute 這個標籤的靜態方法(爲了方便,我設計爲public或者private均可,這實際上由各個實現了 IDomainClient 接口的數據庫對象類來決定),並且反射執行它。當然,僅僅執行這個靜態方法一次就足夠了。 


我最後總結一下主要的設計初衷:雖然我們使用OOP工具進行數據持久化方面的編程,但是往往在許多人那裏與面向實際應用領域的OOAD的結果並不一致。例如對於一些沒有經驗的軟件工程師,他可能認爲成百上千類領域對象的各個實例的更新是調用那些理應依賴於這個對象影響的對象的方法來進行級聯更新的。運行時當然是這樣的,但這是排好隊幹活的“機器”所做的事,而不是設計師所關心的大事。設計師負責研究把機器放進工位使其依照一定關係行事的策略,即那個“you don't call me, we’ll call you”的好萊塢原則所表現的靈活性。然而,我們在不少ORM實現中看不到正常的觸發器框架,甚至看到根本不是由客戶去註冊反而要求服務端去註冊觸發器這種可笑的現象,這不能不說是一個硬傷。
 

 

 

面向對象有它的本質要求。如果你的編程僅僅是“基於對象”而不是“面向對象”的,雖然你也能收到一些“代碼封裝成類型”的好處,但是你其實很難用到真正深入的面向對象軟件工程設計技術。  

面 向對象ORM非常重要,堪稱面向對象軟件工程技術的核心。但是,有很多ORM只是“基於對象”的,不是“面向對象”的。面向對象的ORM應該與面向對象的 軟件工程技術一樣,首要問題是:解決基於對象的結構化技術(如今所有頑固堅持結構化技術的人都使用OOPL語言來說明自己的理論,因此OOPL不等代表 OO的水平)與基於多態的面向對象技術的“阻抗不匹配”現象。  

套用面向對象技術的本質特種,面向對象ORM應該有以下本質特徵(下面是用了熟悉的c#的術語):  

1. 自動維護類型定義。我們把一個對象“丟給”面向對象ORM,它就應該自動分析對象的Field、Property。如果在使用一段時間之後我們的對象類型定義改變了,原來的數據應該仍然能夠回覆爲新的類型的對象,只不過有些新增字段成爲默認值。例如:  

  User u=null;  
  //todo: 產生u實例  
  using(var db=Domain(數據庫連接))  
  {  
  db.Save(u);  
  db.Commit();  
  }  
db事先並不知道“User”這個類型,它應該“臨時”反射User類型並記錄下來。那些要求我們依據關係數據庫的數據字典來寫class代碼的想法可謂“居心叵測”。  

2. 標識唯一性。至少在同一個進程中(也就是在同一個ORM環境中)兩個不同的查詢,如果邏輯上應該有相同的對象返回,那麼ORM就應該體現這個規則。例如有 一個過程是“保存工單記錄”,工單中有字段記錄負責評估工單的產品經理,另外有一個過程是“查詢某個項目組的產品經理”。看上去這兩個過程沒有緊密的邏輯 聯繫,但是他們有數據聯繫。如果一個地方建立個一個產品經理對象並調用了第一個方法,另一個地方隨後調用了第二個方法,那麼對於同一個產品經理,第二個方 法不應重新建立新的內存對象,而應該返回第一個方法所使用的那個對象(除非調用第二個方法時第一個方法使用的那個對象已經被GC釋放了)。  

顯然,你的ORM應該有自己的緩存機制來維護對各個對象的弱引用。緩存並不是僅用來提高查詢速度的,還有邏輯意義上的用處。  

3. 繼承性。如果上述例子中的變量u被實例化爲一個從User類繼承的“系統管理員”類,數據庫當然應該可以保存,並且在隨後“查詢系統管理員”操作中可以正確返回系統管理員的全部字段。顯然,子類和父類在數據庫中肯定要分開成不同的類型(或者叫做“表”)。  

例如假設Domain數據庫類型的Query <T>返回所有T類型對象的一個QueryProvider(Linq定義的):  
  User u=null;  
  u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。  
  using(var db=Domain(數據庫連接))  
  {  
  db.Save(u);  
  db.Commit();  
  var result=(from u in db.Query <系統管理員> where u.姓名=="大寶" select u).FirstOrDefault();
  //todo: result.Print();  
  }  

4. 多態性。  

  User u=null;  
  u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。  
  using(var db=Domain(數據庫連接))  
  {  
  db.Save(u);  
  db.Commit();  
  var result=(from u in db.Query <User> where u.姓名=="大寶" select u).FirstOrDefault();  
  //todo: result.Print();  
  }  
注意result的定義類型是User而不是“系統管理員”。多態讓我們寫出“引擎式”的代碼,這個引擎拖動的車子是虛構的、通用的。ORM應該支持OO的這個本質要求。  

5. 網狀關聯。ORM應該隱藏面向對象數據庫與關係數據庫在處理關聯方面的差別。  

  假設User中有一個“配偶”字段,並且有一個“情人”集合,查詢“系統管理員的配偶和情人”方法可能這樣寫:  

  User u=null;  
  u=new 系統管理員(){姓名="大寶"}; //已經設置(例如使用一個Attribute在class中聲明)“姓名”在數據庫中是唯一的。  
  //todo: u.配偶=......  
  using(var db=Domain(數據庫連接))  
  {  
  db.Save(u);  
  db.Commit()  
  var result1=from u in db.Query <系統管理員> select u.配偶;  
  //todo: result1.ForEach(p=>{p.Print();});  
  var result2=(from u in db.Query <系統管理員> select u).SelectMany(u=>u.情人);  
  //todo: result2.ForEach(q=>{q.Print();});  
  }  
如果你使用面向對象數據庫,那麼從User到它的配偶之間以及每一位情人之間的存儲關聯是“一步到位”的,而不是像關係數據庫那樣需要使用inner join。因此,面向對象昂數據庫(理論上)應該比關係數據庫速度快至少10倍。  

不應該強迫對象類型之間關係模仿關係數據庫的“外鍵”來建立,應該使用上面的自然、OOPL原始的形態。這樣,如果你的ORM的底層是關係數據庫,例如是SQL Server,那麼你的QueryProvider(Linq)實現就不得不將關係翻譯爲關聯操作。  

6. 延遲加載。顯然,當我們查詢一堆User出來之後,它的“七姑八姨”等關係對象不需要加載到內存裏(否則這個加載操作就太可怕了),但是當我們訪問關聯對象時應該自動從數據庫中加載到內存。對於引用單個對象和引用集合對象都是應該這樣的。  

7. 級聯更新。如果我們實例化一個User類型對象,並且給它的“配偶”賦值,那麼在保存這個User類型對象的時候就應該自動保存(新增或者更新都叫是保存 操作)它的配偶,而不需要我們在程序中去寫保存配偶的代碼。如果我們查詢出一個User,他有很多情人,我們用程序向他的“情人集合”裏插入一個情人或者 刪除一個情人,然後保存他,那麼ORM應該自動也去保存這個情人或者刪除它與這個情人的數據庫內連接,但是不需要重複保存那些沒有動過的情人對象。 

 

 

ORM解決的主要問題是對象關係的映射。域模型和關係模型分別是建立在概念模型的基礎上的。域模型是面向對象的,而關係模型是面向關係的。一般情況下,一個持久化類和一個表對應,類的每個實例對應表中的一條記錄,類的每個屬性對應表的每個字段

ORM的缺點是會犧牲程序的執行效率和會固定思維模式。  
  從系統結構上來看,採用ORM的系統一般都是多層系統,系統的層次多了,效率就會降低。ORM是一種完全的面向對象的做法,而面向對象的做法也會對性能產生一定的影響。  

  開發系統時,一般都有性能問題。性能問題主要產生在算法不正確和與數據庫不正確的使用上。ORM所生成的代碼一般不太可能寫出很高效的算法,在數據庫應用 上更有可能會被誤用,主要體現在對持久對象的提取和和數據的加工處理上,如果用上了ORM,程序員很有可能將全部的數據提取到內存對象中,然後再進行過濾 和加工處理,這樣就容易產生性能問題。  
  在對對象做持久化時,ORM一般會持久化所有的屬性,有時,這是不希望的。  
  但ORM是一種工具,工具確實能解決一些重複,簡單的勞動。這是不可否認的。但不能指望工具能一勞永逸的解決所有問題,有些問題還是需要特殊處理的,但需要特殊處理的部分對絕大多數的系統,應該是很少的

 

 

ORM優勢和缺點:

優勢:ORM自其概念被提出,就得到了無數的響應,花樣繁多的應用框架更是應接不暇。可見,他是有其獨到的優勢的。那麼他的優勢有哪些那:

首先,ORM最大的優勢。
        隱藏了數據訪問細節,“封閉”的通用數據庫交互,ORM的核心。他使得我們的通用數據庫交互變得簡單易行,並且完全不用考慮該死的SQL語句。快速開發,由此而來。

第二:ORM使我們構造固化數據結構變得簡單易行。
         在ORM年表的史前時代,我們需要將我們的對象模型轉化爲一條一條的SQL語句,通過直連或是DB helper在關係數據庫構造我們的數據庫體系。而現在,基本上所有的ORM框架都提供了通過對象模型構造關係數據庫結構的功能。這,相當不錯。

缺點:
第一:
        無可避免的,自動化意味着映射和關聯管理,代價是犧牲性能(早期,這是所有不喜歡ORM人的共同點)。現在的各種ORM框架都在嘗試使用各種方法來減輕這塊(LazyLoad,Cache),效果還是很顯著的。

第二:
         面向對象的查詢語言(X-QL)作爲一種數據庫與對象之間的過渡,雖然隱藏了數據層面的業務抽象,但並不能完全的屏蔽掉數據庫層的設計,並且無疑將增加學習成本.

第三:
         對於複雜查詢,ORM仍然力不從心。雖然可以實現,但是不值的。視圖可以解決大部分calculated column,case ,group,having,order by, exists,但是查詢條件(a and b and not c and (d or d))。。。。。。


        世上沒有驢是不吃草的(又想好又想巧,買個老驢不吃草),任何優勢的背後都隱藏着缺點,這是不可避免的。問題在於,我們是否能容忍缺點。ADA代碼雖然 易用性很差,但是US.DoD(the department of defense)欣賞他的運算速度;.net平臺很不錯,但是他是MS的。^_^

 ORM爲何而生

          在數月以前,我有幸參加了一個公司內部的組件發佈會。令我深感意外的事,一向無人關心的組件發佈會這次變得人山人海,在漫長的新版本介紹之後。每個開發組 長都跳出來抱怨上一個版本的問題,並且宣佈與剛發佈的新版本也是無法滿足他們的需要的。一切都是如此的混亂,以至領導層不得不採用鎮壓的方式來平息怒火衝 天的人們。
       在會後的那個晚上,我仔細回想了這次衝突。因爲據我瞭解,這一系列的組件非常完美的完成了他所被期待的功能。可是爲什麼還是會被抱怨如此那。
         我覺得,可能,他(組件)是沒有被正確使用了。

不知道還有誰記得James Elliott 的那句話,

As good object-oriented developers got tired of this repetitive work, their typical tendency towards enlightened laziness started to manifest itself in the creation of tools to help automate the process. When working with relational databases, the culmination of such efforts were object/relational mapping tools.

    ORM構架只能是一個helper,他定位與此,而不是完整的數據持久層。他的設計者從來就沒把他定位於取代一切的超級美女。ORM致力爲長久以來的程序員與”重複勞動”的戰爭而助拳。與任何一個helper一樣,他有自己的不足,他有優點也有缺點。
       無數的開發人員試圖將使用ORM的框架構架自己項目的數據持久層,很多人感受到了ORM的優勢,他們歡心鼓舞。但是很不幸,也有很多人失敗或是深受蹉責。
         還有許多人,無奈的編寫着很多ORM不適合作的事情。其實想一想,被自己捨棄了的以前的helper工具,難道真的一無是處了?

ORM與DB Helper Library:

      很多人可能都接觸過這類的helper,每個公司都有自己的helper。許多Helper提供了很多的強大的功能,封閉交互底層,實體類支持,提供 SQL翻譯功能。ORM比之這些Helper只是多提供了一層,他嘗試封閉的自動化的(或是映射文件)來實現關聯。以前,這都是我們手打的。(靈活替換數 據庫也算ORM優點, )
        問題就在與有些人發現封閉的自動化關聯滿足他們需要了,所以ORM對他而言是成功的。而有些人發現封閉的自動化關聯不適合他們的項目,所以ORM被詬病。
          寫到這裏,我想不用多言了。該結束了。

           我的觀點是ORM試圖取代helper,爲此提供了更多的功能。他爲了應付更加嚴格和複雜的企業需求而不斷髮展,在很多情況下,這些工具開始具有自身的復 雜性,使得開發人員必須學習使用它們的詳細規則,並修改組成應用程序的類以滿足映射系統的需要,使用它們所面臨的複雜性反而蓋過了所能獲得的好處。在我們 的大部分項目中Helper依然是我們構建數據持久層的主力,ORM或許在有些項目(模塊)中可以獨攬一切,但是ORM(就目前而言)無法面對一切考驗。

發佈了42 篇原創文章 · 獲贊 6 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章