功夫看了槍版(為自己汗顏一下,實在是等不及了,而電影院多少年沒有進去了已經),然後開始在網上找相關評論,就好像是自己的東西一樣,期待著人們有好的反應,結果大家也知道,毀譽參半,或者說批評還要多一些,說星爺放棄了擅長的無厘頭,玩起來了特效,失去了自我。
Persistore是什嗎? 一個我正在開發的for .Net的O/R Mapping架構,大家可能奇怪了,現在成熟半成熟的.Net下的O/RM都已經多得讓人眼花繚亂了,為什麼還要自己開發一個?! 難道我這麼喜歡無意義的重複開發,並且想依靠這個東西來證明自己的能力?
再回到功夫上來,可以說,我一向欣賞的是香港電影講故事的能力和星爺無厘頭的表演,對於國產大片(以英雄、埋伏為代表)和好萊塢大片卻並不感冒,因為我需要的不是視覺的衝擊而是看電影時的放鬆和快樂,哈哈一笑,僅此而已,然而功夫在這方面帶給我的這些東西非常少,可以說讓我很“失望”,但是同時我們應該知道,功夫是星爺的再一次嘗試,為了圓一個兒時的夢,用三年時間,換來一部風格迥異的電影,當然他自然也會從票房著想,為了國際化,更多地簡化語言,強調動作。
我不喜歡功夫,但是我欣賞星爺的這種嘗試和努力,同時Persistore也是我自己的嘗試和努力,因為我一直以來就想開發我所希望的O/RM,.Net出現已經4年了,而我現在才正式開始進入.Net開發,然而我這個想法一直以來就沒有改變過。
那麼Persistore有哪些特性?它憑什麼可以讓我不選擇其它的成熟解決方案?就像駭客帝國、指環王中的特效已經這麼好了,為什麼功夫還要玩特效?
1、純實體類
這是我對自己的O/RM最重要的一個要求,純實體類不僅輕,而且可以便於移植(有人說了,誰會去移植?!),可能是我太偏執的原因吧。
2、自動對應
Persistore不需要自訂屬性和XML檔案的支援便可實現映射。 我們已經有了資料庫模型了,我們已經有了實體類了,為什麼還需要再去維護映射?!
3、關係維護
OnetoOne、OnetoMany、ManytoMany、SelfAssociate支援,正如yyanghhong所說,不支援關係的O/RM還不如直接用typed-dataset.
4、自動建立資料庫結構(需要自訂屬性支援)
Class->Database已經成為潮流了,本來不準備支援的,但同事AdamBear說得很對,在早期的迭代式開發中,難以建立完整的資料庫模型,所以實體類是優先考慮的。和其它架構不一樣的是,Persistore不需要建立額外的字典資訊表,同時可以在主鍵不改變的情況下動態添加、刪除、更新欄位的定義。
5、lazy-loading
在支援關係維護後,沒有遲載入的話,那麼對於效能就是致命的下降。Persistore可以遲載入對象屬性、實體集合,並且對於遲載入的實體集合只使用一次查詢完成。
6、實體繼承
Persistore完全支援實體繼承,可以同時支援JoinTable和UnionTable兩種持久化方案,即分表儲存和單表儲存。
7、對象化查詢
現有的O/RM中只有極少數的(如ECO)支援真正的對象化查詢(即UML2.0中的OCL),hibernate的HQL實際上還是sql的變種,Dataobjects.Net裡的也還是sql,不過比sql還難理解,Persistore的OCL支援同樣也是有限的(擴充了函數,但減弱了集合操作,因為OCL最終將解析成SQL),它的形式如下:
Department.Employees->Sum(salary) > 100
重要的是對關係的查詢,而不僅僅是屬性的過濾。
8、跨資料庫平台和SqlBroker
從一開始,Persistore的設計就是要支援多資料庫平台的,各大資料庫廠商對標準SQL的支援越來越好,同時標準SQL本身的功能也在增強,這使得平台無關的SQL語句已經可以完成絕大多數功能。通過Persistore執行的sql只能是被其支援的標準SQL。
9、View、Store Procedure支援
這是一個資料庫應用程式必不可少的,同時彌補上面SqlBroker的不足。
10、其它特性
Criteria查詢構造、NULL處理、事務支援(transaction和savepoint)、不完全實體物件查詢、多種"髒"標誌擷取方法(default value、snapshot value、dynamic proxy)、延遲更新和批次更新。。。
還需要多久?
目前差的是OCL和ANSISQL的解析(文法分析已經完成)、Store Procedure的封裝以及最重要的實體類自動產生工具(CodeDG已經夠靈活了,但它還不能提供Persistore最需要的外鍵約束資訊)
如何使用?
一個簡單的例子:
Session s = new Session(DB.CONNECTSTRING);
Address a1 = new Address();
a1.id = "001";
a1.street = "any";
Class c1 = new Class();
c1.id = "01";
c1.name = "grade1";
Student s1 = new Student();
s1.Class = c1;
s1.address = a1;
s1.id = "0001";
s1.name = "progame";
Assert.IsTrue(s.Save(s1));
Student s2 = (Student)s.Load(typeof(Student), "0001");
Assert.AreEqual(s1.name, s2.name);
Assert.AreEqual(s1.Class.name, s2.Class.name);
Assert.AreEqual(s1.address.street, a1.street);
Student s3 = new Student();
s3.id = "0001";
s.Load(s3);
最後說點什麼
寫代碼真的好累,有時候真的不想寫了,但想想星爺,想想功夫,即使做出一個被人批評的東西,但至少事後我可以無悔地說:我做過了!