一名紐約女技術員的JDO經驗

一個紐約女技術員的JDO經驗

JDO應用介紹
by Teresa Lau
譯自:http://www.sys-con.com/java/articleprint.cfm?id=1899

(譯者注)本文以一個實際的具有一定相互關係的類結構實例和KodoJDO產品作基礎,介紹JDO的原理、使用及特點。尤其是與傳統JDBC技術的對比,比如一個類的代碼從480行減少到140行的現實,說明JDO對代碼的減少。另外,本文作者是一位具有五年以上Java顧問經驗的女中豪傑,擁有碩士學位,目前工作於紐約。

Java Data Object(JDO) 是一個用於存取某種數據倉庫中的對象的標準化API。

使JDO從各種數據對象存取技術中異軍突起的是它的高度的易用性和靈活性。

JDO提供了透明的對象存儲,因此對開發人員來說,存儲數據對象完全不需要額外的代碼(如JDBC API的使用)。這些繁瑣的例行工作已經轉移到JDO產品提供商身上,使開發人員解脫出來,從而集中時間和精力在業務邏輯上。另外,JDO很靈活,因爲它可以在任何數據底層上運行。JDBC只是面向關係數據庫(RDBMS鳭DO更通用,提供到任何數據底層的存儲功能,比如關係數據庫、文件、XML以及對象數據庫(ODBMS)等等,使得應用可移植性更強。

概述



描述符(Metadata)和增強器(Enhancer)



在JDO中,任何需要存儲的類必須是PersistenceCapable(可存儲的),而任何用到這些類的其它類必須是PersistenceAware(存儲可知的)。看上去有點複雜,不過好消息是採用JDO的透明存儲技術,你不需要在代碼中將你的類去實現javax.jdo.PersistenceCapable接口或PersistenceAware接口。你只需要象往常一樣寫一個類即可,JDO廠商會提供一個增強器,這個增強器會改造你的類代碼(譯者注:就是.class文件,改造class中的二進制代碼並不是一件很高深的事,有很多工具可以提供給你對class文件進行改造,比如在某個方法開始和結束時輸出日誌等等),根據你的描述符使之實現PersistenceCapable接口。你需要做的唯一的額外工作就是爲你需要存儲的類寫一個XML格式的描述符文件。附件1顯示了一個我在後面的代碼示範中會用到的描述符文件。(附件17和本文的代碼可以在www.sys-com.com/java/sourcec.cfm下載。)

描述符一般來說很短,在默認條件下寫起來一點也不難,JDO從類本身已經獲取了大量的信息。你僅在下列情況下在描述符中添加額外信息:
。你需要改變JDO的默認操作方式,比如,使一個屬性不存入數據庫,即使它沒有標記爲transient
。有些額外的信息是JDO無法從類本身獲取的,比如:哪一個屬性你想設爲數據庫中的主鍵(譯者注:只有使application identity時纔有這個必要),或者某個集合類型(Collection或子接口/類)中的元素是什麼類型

存儲管理器(PersistenceManager)



當你的類被增強後,你就可能使用PersistenceManager來存儲你的對象了。要獲取一個PersistenceManager,先要設置一些屬性,通常包括下列信息:
。數據庫連接信息
。JDO產品的類名
。默認的一些屬性,包括連接池大小等等

附件3的第23行顯示瞭如何設置一個Properties對象,從而獲取一個JDO的PersistenceManagerFactory(相當於JDBC連接池中的DataSource),進而獲得一個PersistenceManager對象(相當於JDBC中的Connection對象),之後,你可以用這個PersistenceManager對象來增加、更新、刪除、查詢對象(這也是我在後面將會討論的)。當你的這些操作做完後,你需要關閉主這個PersistenceManager對象,以釋放它使之能被再次使用(比如另一個線程)。

附件3的代碼片斷告訴你如果使用JDO來存儲和查詢對象。利用一個PersistenceManager類型的對象pm,你可以使用pm.makePersistent()方法來將一個新的對象保存到數據庫(第68行)。一個對象僅僅在第一次出現的時候才需要保存到數據庫(譯者注:更嚴格一點,只在沒有已存儲的對象引用時才需要顯式地調用makePersistent()方法),當它已經在數據庫中存在以後,可以直接通過訪問其屬性來更新該對象的信息。所有的更新在當前的Transaction(數據庫概念:事務)被提交時全部保存到數據庫中。而如果你不希望保存主這些更改,只需要簡單地rollback當前的Transaction即可(第15到17行)。類似地,你可以調用pm.deletePersistent()刪除一個對象(第26行)。

要訪問已經存儲過的對象,可以簡單地遍歷其Extent(類的所有擴展),這是一個對該類對象的邏輯上的總稱(第12到15行)。

如果你希望有選擇地(而不是一古腦地)取出某個類的所有對象的一個子集,你可以創建一個Query(查詢)。要做到這一點,調用pm.newQuery()來獲得一個Query對象,並傳入參數:候選對象集合和一個過濾器。候選對象集合可以是一個Collection或者一個類的Extent。過濾器是一個JDOQL(JDO Query Language)語句。當你創建了這個Query以後,就可以執行它來獲得一個符合條件的集合(Collection,第22到26行)。JDOQL是JDO的查詢語言;它有點象SQL,但卻是依照Java的語法的。這裏的例子只是一個簡單的示範;使用JDOQL,你的過濾串可以寫得很複雜。另外,如果你在過濾串中使用綁定的參數的話,你可以寫一個簡單的查詢然後執行很多次,每次給出新的參數值。關於JDOQL有很多資料可以參考,參見本文的資源列表。

一個對象存儲的例子



要找出JDO是否象Sun說的那麼好,我會寫一些代碼,分別使用JDO和JDBC來存儲我創建的Book對象(見附件4)。這個Book對象有一個name屬性和一個Block對象。爲使示例有趣一些,Book對象有一個限制:每本書由其名稱唯一確定,也就是說,你不能加入兩本同名的書。

一個Block(塊)是Book的組成部分,它可以是Document、Chapter或Section。最頂層的Block是Document類型的,並且可以包括任意數量的Chaptor Blocks。每個Chaptor Block可以包括任意數量的Setion Blocks,因此這些Block中有一種嵌套的關係。在每一個Block中,我們用一個HashMap來存放任意數量的其它Block的鍵值對。

附件5列出了一個我的例子中做測試用的Book。這本書包括兩章(Chaptor),第一章有一節(Section),還有第二章。特別地,第二章有一個屬性:Color=Red。

用這個圖書的例子, 我要實現以下一個存儲功能:

。增加:看看我能否成功地向數據庫中添加兩本書,並且如果我用同樣的名字加入第三本書,將會產生一個名稱唯一性檢查失敗的異常
。更新:看看我是否能夠更新一本書:增加一個屬性“Comment”到它的根Block中。當我提交(commit)的時候,這些更新應該被保存下來,而如果我回滾(rollback),這些更新將被丟棄。
。刪除:看看能否通過Query查詢一本書然後從數據庫中將它刪除。

如果沒有JDO, 我通常會這樣設計:先設計幾個相關的關係數據表來存儲書中的數據,然後使用SQL和JDBC來存儲/讀取這些表。由於長度的關係,我不會在這裏列出我的JDBC實現,不過如果感興趣,你可以從JDJ 網站上下載。注意,爲了通過JDBC/SQL實現以上這些功能,我必須寫很長一段代碼(480行!)。我現在要做的是讓你看看用JDO來實現同樣的功能會有多麼的簡單。

用JDO存儲一個Book對象



用JDO來存儲一個Book對象時,儘管我使用與JDBC方式中同樣的Book主鍵類,但Block的ID屬性已經完全沒有必要。在JDBC方式中,必須用ID屬性來在內部引用數據表中的不同的Block。但在JDO中,我根本不需要這個屬性,因爲JDO會自動地在底層處理它。

爲了標明Book對象是需要存儲的,我寫了一個描述符來標記Book和Block類(見附件1)。在描述符中,我爲Block類的children集合屬性標明其元素類型是Block(第10到11行),而HashMap的鍵和值的類型都是String(第12到14行)。此外,由於ID屬性並不是Block真正需要的,我在描述符中標明它不需要存儲(第8行)。在Book的描述符片斷中,我標明nm(名稱)屬性是它的主鍵(第5行),因此Book類需要使用自定義的標識類型(Application Identity),類名是BookKey(第4行)。BookKey類的代碼見附件6。

在本例中,我使用的JDO產品是KodoJDO(採用關係數據庫作底層)。市場上有很多JDO的產品(Implementation);你可以選擇其中任意一種,而你的代碼不需要作任何變化。底層的關係數據庫我選擇Enhyda InstantDB(一個Kodo產品附帶的關係數據庫)。JDO的精髓在於開發人員不需要知道某個JDO產品是如何將數據存入數據庫的,所以我也不需要設計任何數據表,儘管我們底層使用的是關係數據庫。Kodo提供了一個名爲schematool的工具,根據我的描述符自動地創建需要的數據表結構。我所需要做的全部事情就是運行下面的命令來準備數據庫底層(譯者注:實際上,KodoJDO2.4.0以上版本就可以完成自動的數據庫同步,這一步都可以省略。不過只建議在開發時使用):
schematool action refresh Book
schematool action refresh Block

下一步我正常地編譯我的類,然後用Kodo的增強器(Enhancer),名爲jdoc,來增強我的類代碼(譯者注:這些步驟可以採用Ant批處理工具來完成,大多數JDO廠商都提供Ant任務支持):
jdoc Book
jdoc Block
jdoc BookPersistJDO

這裏,只要我將未增強的class文件(Book.class,BlockPersist.class,BookPersistJDO.class)和描述符放到jdoc能找到的位置,jdoc就會更改這些類代碼,使之成爲PersistenceCapable,而沒有標記爲可存儲的類將會被增強爲PersistenceAware的。在本例中,Book.class和Block.class會被改造爲PersistenceCapable的,而BookPersistJDO.class會被改造爲PersistenceAware的。(譯者注:此處需要說明一下,多數意見提倡非存儲的類只通過訪問器(accessors,即get/set/is方法)去訪問可存儲對象的屬性,這樣,這些非存儲的類根本不需要強化,以減少複雜性。)

增強了這些類之後,任何對我的對象進行操作的工作都可以通過PersistenceManager完成。用我前面提到過的那些代碼,我可以很簡單地獲取一個PersistenceManager pm,然後用它來增加、刪除、更新一本書。附件7顯示了我的BookPersistJDO.java的代碼片斷。裏面的方法addBook(第3行)示範了我如何通過JDO增加一本書,而deleteBook(第13行)示範了我如何刪除一本書。

爲通過名稱來取一本書,我使用JDOQL過濾器創建了一個Query。執行這個Query後,我得到一個符合條件的對象集合(Collection)(第25到29行)。從中得到一個Book對象後,我直接更改其屬性然後提交。

附件3顯示了我的JDO方式的例子的測試結果。結果符合我的預期。首先,我成功地將一本書加入數據庫,然後加了另一本同名的書,結果產生了一個JDOUserException,告訴我違反了名稱唯一性的規則。接着,我可以更新一本書的信息,提交這些更新,或者通過回滾放棄這些更新。最後,我可以從數據庫中通過名稱找出一本書,然後將它刪除。

兩種版本的比較(JDBC vs JDO)



通過使用JDO和JDBC來解決同樣的問題,我觀察到以下內容:
1、採用JDO的話,我可以做到與JDBC同樣的事。我可以通過JDOQL來查詢對象;通過標記Book類的nm屬性爲主鍵來保證書的名稱唯一性;另外可以增加、刪除、更新這些對象。
2、JDO使我的Transaction處理更加容易。在JDBC方式中,因爲一本書實際上被對應到四個不同的關係數據表中的許多條記錄,我必須保證所有的插入和刪除操作在同一個Transaction中完成。相反,JDO只需要一個操作就可以保存所有這些變化,而我不需要使用Transaction來維護這個操作的原子性。
3、BookPersistJDO.java只有140行,比BookPersistJDBC.java(480行)少很多,這些事實都說明JDO使我的代碼少了很多。尤其是我的類之間關係有嵌套的特性使得在關係數據庫中的表結構比較複雜。在我的JDBC實現中,我不得不花很多心思來設計我的數據庫,從而存儲和獲取這些嵌套的數據。我不得不用一個ID字段來表示每一個Block,並使用一個外鍵來表達父/子關係。在JDO實現中,我根本不需要考慮這些問題,一切都被正確地存儲下來。
4、我爲了提高性能而在JDBC實現中加入的緩衝機制在JDO中並不需要,因爲JDO產品一般都包含了性能優化和緩衝。這些也節約了我很多工作量,因爲我不需要擔心我的緩衝是否始終與數據庫保持同步。

在這些區別之外,JDO產品和我的JDBC實現可能沒有多大區別。比如,這個JDO產品,使用了一個關係數據庫,可能也採用類似的表結構設計和ID產生機制,並且用JDBC來存儲數據。然而,關鍵在於我不需要了解這些實現上的細節:這些負擔被轉移到具有專業水平的JDO廠商身上,也正是這些人更希望在這些細節上做得更好。另外,這些廠商也可以自由地選擇在其它類型的存儲技術中實現存儲,比如對象數據庫或文件等等,這些給我們在選擇具體存儲方式上在有很大的靈活性。

結論



JDO提供了很多好處:
。它具有所有必須的數據存儲功能:增、刪、改、事務、數據唯一性、緩衝
。它免除了開發人員的一大堆繁瑣的工作,使代碼更易讀和易維護
。它獨立於具體的廠商,防止了廠商依賴性
。儘管我的代碼沒有顯示,它可以在任何數據倉庫中工作,使開發靈活而可移植

JDO是一種值鑽研的技術。本文只是你的一個起點;更多的信息請看下面的資源。

資源

。一站式的網站:http://www.jdocentral.com/
。規範:http://access1.sun.com/jdo/
。Roos, R. (2002). Java Data Objects. Addison Wesley出版社:http://www.ogilviepartners.com (譯者注,我有該書作者給我的pdf版本,可以與大家共享,但切勿作商業用途)
。本文例子用到的JDO產品:SolarMetric: http://www.solarmetric.com/Software/Kodo_JDO (譯者注:KodoJDO是目前做得最好的產品,性能方面優化特別多,尤其是最新的2.5.0beta版本。該產品的開發團隊基本上都來自於麻省理工大學。KodoJDO目前的缺點是不象南非的HemiSphere公司的JDOGenie產品一樣,有獨立的描述符編輯工具,只能搭配JBuilder7以上使用。不過在我的建議下,他們準備在3.0版本中加入這樣的工具。)

JDO的屬性配置



附件2提供了我後面用到的屬性文件。我用了一個關係數據庫,第14行包含了數據庫連接的信息。第6行包含我用到的JDO產品的類名(譯者注:即廠商對PersistenceManagerFactory的實現類)。第8到10行是對PersistenceManager的默認設置,標明我使用Optimistic Transaction,以及數據在rollback時可從緩衝中恢復,在提交時不保留這些值(譯者注:目的是保證有些數據庫中的觸發器產生的更新可以再從數據庫中讀回來)。還有很多的細節,可以設置進行Transaction時採用哪些選項。請閱讀JDO的API來找到它們的含義,並在需要的時候使用。

JDBC實現

這裏我簡單地描述一下我如何通過JDBC存儲Book類。知道這裏麪包括多大的工作量後,你會更加理解JDO爲你所做的一切。

我創建了四個表來存儲Book(見圖1)。爲保證數據唯一性,Book表的nm字段標記爲單一索引(譯者注:實際上就是標爲主鍵)。爲跟蹤每個塊(Block)的屬性和其子集,我爲每個Block增加了一個blockId字段。這個BlockId字段在每個Block加入數據庫的時候產生(在已經存在的最大的Block表中的blockId值的基礎上加1)。

增加一本書涉及到將一個Book對象的信息分解爲四個表:Book,Block,BlockRelation,以及BlockAttr。特別地,每個Block需要生成一個blockId。進一步,最麻煩的是Blocks是嵌套/遞歸的,我必須寫入遞歸的代碼將這些數據插入到數據庫。

在附件5創建Book的例子中,這些數據表顯示在圖2中。你可以看到,一本書被轉換成四個表中的很多行,因此,所有的插入操作都必須包裝在一個Transaction中,這樣才能保證一本書被完整地加入或完整地取消,永不殘缺。同樣的,刪除一本書涉及到從四個表中找出所有合適的需要刪除的行,並在一個Transaction中刪除以保證這本書被完整地刪除或取消刪除。

爲了更好的性能,我並不想每次有人需要查詢一本書的時候都遞歸地從四個表中取出數據。我創建了一個BookCache,在應用開始運行的時候一下子從數據庫中取出所有的書。當我增加、刪除、更新這些書的時候,我的代碼保證BookCache與數據庫是同步的。所有這些工作都在這個cache中完成,使得取一本書只需簡單地在cache中按名字查找。

仍不完美的地方



撇開以上談到的這些優點,還有一些地方是JDO做得還不夠的:
。它對新開發的項目很好,但如果要將現存的關係數據庫也使用JDO,就需要多做一些映射工作(編輯描述符)
。對開發人員來說,採用JDO後,我們不再需要處理底層的數據庫訪問,所以在性能優化上可能比原來難一點。因爲JDO必須做很多額外的工作,比如跟蹤對象屬性的變化以同步內部的緩衝等等,JDO產品做得如何對性能至關重要
。JDOQL還不支持聚合操作,比如max, min, sum這些SQL能做到的事。(譯者注:在JDO1.0規範的第24章詳細描述了下一步2.0規範應該做到的內容,其中包含這些)
。如果能在編譯時就能找了JDOQL的錯誤就好多了。比如在一個過濾串中,你通過一個字符串來指定一個屬性名,你很容易寫錯名稱,但編譯不會出錯,運行時纔出錯。(譯者注:SQL也存在同樣問題)
。一些人認爲JDO的好處在於你不需要再寫SQL,但真實的情況是你必須學習JDOQL。

作者介紹



Teresa Lau已經作爲獨立的Java顧問五年多了,重點在金融系統上。她擁有計算機碩士學位,目前工作在紐約。

源代碼:


Listing 1 Metadata for my example


1 <?xml version="1.0"?>
2 <jdo>
3 <package name="whs.jdo">
4 <class name="Book"
identity-type="application"
objectid-class="BookKey">
5 <field name="nm"
primary-key="true" />
6 </class>
7
8 <class name="Block" >
9 <field name="id"
persistence-modifier="none" />
10 <field name="children">
11 <collection
element-type="Block"/>
12 </field>
13 <field name="attributes">
14 <map key-type="String"/>
15 <map value-type="String"/>
16 </field>
17 </class>
18 </package>
19 </jdo>

Listing 2 Properties for setting up JDO


1 javax.jdo.option.ConnectionUserName=
Database user
2 javax.jdo.option.ConnectionPassword=
Password of the user
3 javax.jdo.option.ConnectionURL=
URL of the database
4 javax.jdo.option.ConnectionDriverName=
Classname of JDBC driver
5
6 javax.jdo.PersistenceManagerFactoryClass=
com.solarmetric.kodo.impl.jdbc.
JDBCPersistenceManagerFactory
7
8 javax.jdo.option.Optimistic=true
9 javax.jdo.option.RestoreValues=true
10 javax.jdo.option.RetainValues=false

Listing 3 JDO Code Fragment

1 // --- Get persistence manager ---
2 PersistenceManagerFactory factory =
JDOHelper.getPersistenceManagerFactory
(property);
3 PersistenceManager pm =
factory.getPersistenceManager()
4
5 // --- Add ---
6 pm.currentTransaction().begin ();
7 pm.makePersistent (obj);
8 pm.currentTransaction().commit ();
9
10 // --- Iterate Extent & Update ---
11 pm.currentTransaction().begin ();
12 Extent ext = pm.getExtent
(MyClass.class, false);
13 for (Iterator i = ext.iterator ();
i.hasNext();) {
14 MyClass obj = (MyClass)i.next ();
15 obj.setField1("AA");
16 }
17 pm.currentTransaction().commit ();
18
19
20 // --- Query and Delete ---
21 pm.currentTransaction().begin ();
22 String filter ="nm=/"JDO Book/"";
23 Query qry= pm.newQuery(ext, filter);
24 Collection c =
(Collection) qry.execute();
25 Object obj = c.iterator().next();
26 pm.deletePersistent (obj);
27 pm.currentTransaction().commit();
28
39 // --- Close resources ---
30 pm.close();

Listing 4 Book & Block object


1 class Book {
2 String nm;
3 Block block= new Block("Document");
4
5 Book(String name){
6 this.nm = name;
7 }
8
9 void addChild(Block e) {
10 block.addChild(e);
11 }
12 }
13
14 class Block {
15 String type;
16 Integer id;
17 Map attributes = new HashMap();
18 List children= new ArrayList();
19
20 Block(String type) {
21 this.type = type;
22 }
23
24 void addChild(Block e) {
25 children.add(e);
26 }
27
28 void setAttribute(String key,
String attr){
29 attributes.put(key, attr);
30 }
31 }

Listing 5 Create Test Book


1 Book book = new Book("Intro to JDO");
2 Block chp1= new Block
("Overview", "Chapter");
3 Block sec11 = new Block
("Advantage of JDO", "Section");
4 chp1.addChild(sec11);
5 Block chp2 = new Block
("Example", "Chapter");
6 chp2.setAttribute("Color", "Red");
7 Block sec21 =new Block
("JDBC Code", "Section");
8 Block sec22 = new Block
("JDO Code", "Section");
9 chp2.addChild(sec21);
10 chp2.addChild(sec22);
11 book.addChild(chp1);
12 book.addChild(chp2);

Listing 6 BookKey.java


1 public final class BookKey {
2 public String nm = null;
3 public BookKey(){}
4
5 public BookKey(String nm) {
6 this.nm = nm;
7 }
8
9 public boolean equals (Object o){
10 if (o == this) return true;
11 if (!(o instanceof BookKey))
return false;
12 return((BookKey)o).nm.equals(nm);
13 }
14
15 public int hashCode () {
16 return nm.hashCode();
17 }
18
19 public String toString() {
20 return nm;
21 }
22 }

Listing 7 BookPersistJDO.java


1 class BookPersistJDO {
2
3 public Book addBook (Book book)
4 throws JDOUserException {
5 PersistenceManager pm =getPM();
6 Transaction tran =
pm.currentTransaction ();
7 tran.begin ();
8 pm.makePersistent (book);
9 tran.commit ();
10 return book;
11 }
12
13 public void deleteBook (Book book){
14 PersistenceManager pm =getPM();
15 Transaction tran =
pm.currentTransaction();
16 tran.begin ();
17 pm.deletePersistent (book);
18 tran.commit ();
19 }
14
15 public Collection getAllBooks() {
15 PersistenceManager pm = getPM ();
17 String filter ="";
18 Extent extent =pm.getExtent
(Book.class, false);
19 Query qry = pm.newQuery
(extent, filter);
20 return (Collection)qry.execute();
21 }
22
23 public Book getBook(String name) {
24 PersistenceManager pm = getPM ();
25 String filter="nm==/"" +
name +"/"";
26 Extent extent = pm.getExtent
(Book.class, false);
27 Query qry = pm.newQuery
(extent, filter);
28 Collection c =
(Collection) qry.execute ();
29 return (Book) c.iterator().next();
30 }
31 }


Additional Code for this Article zip file ~7.78 KB

附圖


圖 1
CSDN_Dev_Image_2003-5-61136520.jpg

圖 2
CSDN_Dev_Image_2003-5-61136522.jpg

圖 3
CSDN_Dev_Image_2003-5-61136524.jpg


網友評論



JDO Not Vendor Independent
Posted by Scott P. Smith on Mar 4 @ 01:27 PM

A few weeks ago, I attended a one hour talk by Oracle's Director of Technology, Donald Smith covering persistence archetectures. In it he strongly stated that JDO is not completely vender independent. I don't know that myself. I'm just repeating what he said, which conflicts with claims made in this article.


(read & respond...)

--------------------------------------------------------------------------------
Author lacks JDBC knowledge
Posted by Donald Bales on Mar 4 @ 07:39 PM
The whole article became tainted when the author stated: "...JDBC provides persistence only for relational databases..." Not true. JDBC can handle most of the data sources listed. In fact, many JDO implementations utilize JDBC "under the covers". Second, JDO claims to be able to support these other data sources, but I don't see many implementations. JDO provides a slick abstration for relational databases, but it's not the silver bullet that it's hyped to be.


(read & respond...)

--------------------------------------------------------------------------------
JDO Not Vendor Independant
Posted by I Davie on Mar 5 @ 04:51 AM
JDO is meant to be a Java standard not a database standard. Oracle are not interested in JDO because it gives developers choice and Oracle don't like that! If they're forced to move that way they will but not by choice :-)


(read & respond...)

--------------------------------------------------------------------------------
Pro-JDO comments from JDO vendors
Posted by Scott P. Smith on Mar 5 @ 10:12 AM
Another thing that Donald Smith (no relation) from Oracle said was that the only people making positive comments about JDO are JDO vendors. I see "I Davie" is with Versant, which is soon to be a JDO vendor according to their web site.

I am very neutral with regard to JDO. I have never used it. Can we hear comments from someone (who doesn


(read & respond...)

--------------------------------------------------------------------------------
jdo
Posted by bret on Mar 9 @ 11:22 PM
http://www.sys-con.com/java/article.cfm?id=1899


(read & respond...)

--------------------------------------------------------------------------------
Anti-JDO comments
Posted by David Tinker on Mar 14 @ 08:26 AM
Treat anything that anyone associated with Oracle has to say about JDO with caution. Oracle own Toplink, a $10K/CPU O/R mapping tool that competes directly with JDO. If JDO is sucessful who will pay that kind of money for vendor-lock-in O/R mapping? The most expensive JDO implementations are approx $3K with no runtime costs.

I won't say anything about JDO as I work on JDO Genie from Hemisphere Technologies :) Try it for yourself!


(read & respond...)

--------------------------------------------------------------------------------
Non-Vendor Comment
Posted by Chester Arnold on Mar 24 @ 07:49 AM
I agree with David Tinker. You need to learn to try things out and not always believe vendors who are trying to salvage tanking stock prices. I've used a number of JDO implementations including the one the article used (Kodo JDO). The quality of JDO implementations vary widely so trying them out is probably the best thing you can do.

You can find a list of JDO implementations at www.jdocentral.com.


(read & respond...)

--------------------------------------------------------------------------------
Oracle FEAR!!
Posted by Alf on Mar 25 @ 09:57 AM
It is a matter of time. You will see that programmers prefer JDO , and ORACLE will have to offer their own implementation of the JDO Specification .
You CAN


(read & respond...)
--------------------------------------------------------------------------------



本文的版權屬於筆者本人,但歡迎轉載,前提是註明出處和原作者。另外,歡迎在我的專欄中查看我的另幾篇文章,並提出寶貴意見!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章