賀JDO2.0計劃開始啓動!

賀JDO2.0計劃啓動

  近日,欣聞Sun公司正式加入了JDOCentral.com作爲其Charter Member之一,表明了Sun公司對JDO的正式支持和推動。以往,Sun雖然提出了JDO規範,但在正式支持方面總是做得不夠,感覺好象是因爲對其EJB體系會造成衝擊,所以一直只是半推半就地提供有限的宣傳,主力推廣JDO的還是JDOCentral.com這個公益網站。不過現在,JDO規範已經提出來有近一年半了,陸續也有很多優秀的產品涌現出來,看樣子即將形成一股新的旋風,Sun看到時機成熟,這時還不跳出來,更待何時!於是我們也很欣喜地看到,Sun正式加入了JDOCentral,並且,開始了JDO2.0計劃的準備工作。
  信息來源:http://www.theserverside.com/home/thread.jsp?thread_id=20875&article_count=37

  我們已經提到,JDO1.0已經提出有一年半,但似乎大衆的接受程度還不夠,沒有很多應用開發公司表現出足夠的熱情。除了Sun的推動不夠這個原因之外,這也是與與JDO1.0的侷限性是有關的。我們期待JDO1.0能夠解決大多數中小規模數據庫應用的開發,也就是能夠基本取代JDBC,但是不支持映射和數據庫統計功能是JDO1.0的最大缺陷。我就一直期待JDO2.0能夠解決這些問題,至少可以針對JDBC專門提供一組optional API,這樣也可以不影響JDO在其它類型數據庫(比如文件、XML和OODB等)中的應用。總地來說,JDO1.0能夠滿足我們開發數據庫應用中的多數需要,只是加上這些功能將會更爲方便。

  我們現在來看看JDO2.0將給我們帶來什麼。實際上,在JDO1.0規範中已經在最後一章提出了一些已經爲多數人所關心的功能,但由於想法還不成熟,或者大家意見不一致,還有待實踐的進一步驗證,於是只好放到JDO2.0再去規範化。因此,我們有理由相信JDO2.0的議題首先會包括這些內容,至少大部分內容會被包含。這裏,我簡單地解釋一下JDO1.0規範中推到下一版的議題有哪些:

  1. 嵌套的事務
    事務的支持是一個數據庫必須提供的功能,但實際開發中,我們常常會需要多級的事務,中間的某個操作的失敗不會引起整個事務的回滾,而只是將一小部分操作進行回滾,再採取另外的操作。JDO2.0將會對此進行規範化,當然,可能是作爲一個可選的特性,讓廠商選擇是否實現,不過一旦實現,用戶就可以通過規範的API去執行嵌套的事務處理。
    比如,我們在編寫業務邏輯的時候,可能會有很多個邏輯方法,每一方法都需要對數據對象進行更新操作,也就是說,需要在方法裏面使用一個事務。如果其中一個方法有可能被另一個方法調用,那麼在JDO1.0可能會出現“事務已經開始”的異常,於是,我們只好用下面的代碼來編寫每一個邏輯方法,以保證它們之間的相互調用不會出錯:
    public void logicalOperation1() {
      Transaction tx = pm.currentTransaction();
      boolean newTx = !tx.isActive();
      if(newTx) tx.begin();
      //這裏做一些數據對象的更新操作
      if(newTx) tx.commit();
    }
    在JDO2.0中,我們就不必擔心這個問題,每一方法只需要簡單地開始一個事務,進行數據操縱,然後提交,就行了。
  2. 事務保存點
    這個實際上是JDBC3.0提出的功能規範,它在一個事務中可以讓你回滾到某個指定的點,而不是回滾整個事務。如果底層的JDBC驅動支持JDBC3.0規範,那JDO2.0將會利用這個特性來給應用代碼提供更強的控制。事務保存點與嵌套的事務都是事務處理中的高級功能。這裏提一下,JDO之下的底層數據庫不一定是JDBC數據庫。
  3. 跨PersistenceManager的對象操縱
    即定義標準的接口來對不同的PersistencManager管理的對象之間的關係進行操縱和管理。這一點非常有用,可能可以完成不同的數據源之間的對象關係處理,比如一個存在於MySQL中的對象含有一個引用指向一個Oracle中的對象,JDO可以自動地完成兩者之間的引用調用,不必在應用代碼中進行額外操作,使應用代碼更簡單,更透明化。
  4. 調用增強器的標準API
    JDO2.0會定義一個接口方法來讓應用程序直接調用增強器增強某個類的類代碼。這一點可以保證應用開發過程在增強時的統一性,不受廠商影響。此外,可能可以通過此功能在某些J2EE服務器中做出符合標準的動態增強器(如特定的ClassLoader),以使增強這一步驟對開發過程的影響更小。
  5. 預讀數據API
    我們在寫應用代碼的時候,只需要查詢出一個對象集合,然後通過訪問其屬性來觸發底層的數據庫讀取操作,雖然很透明,但有時候得到的性能並不是很好,比如讀取1000個對象,可能會造成1000多次數據庫的數據傳輸。再比如,有時候我們需要訪問一組對象的某兩個屬性,但JDO可能會將所有的屬性都讀出來,也會造成一定的性能損失,在這一點上,比JDBC要慢。而另外一些情況下,我們需要同時訪問一組對象所相關的另一組對象,而JDO默認都是對被引用的其餘對象進行延遲調入的,在這種情況下,數據處理時間會有所延長。因此,我們希望在特定的JDO查詢之前,我們可以給JDO一點提示,讓它知道如何能夠最有效地得到我們需要的數據。
    JDO2.0可能會定義一些API來讓程序告訴JDO該採取什麼策略在馬上進行的一個查詢中讀取數據,以使應用程序在特定的代碼段中得到最好的性能。
  6. BLOB/CLOB類型的支持
    目前爲止,JDO產品可以選擇不同的方式來將byte[]類型映射成java.sql.Blob,或者將字符串或者其它數據映射成java.sql.Clob,不過具體的映射方式不會作規範化,也許會導致不同的產品運行同樣的應用性能有所差異。
  7. 自動的(雙向)對象關係維護
    這一點是我個人認爲最有用的。我們在寫CMP的EJB2.0時,會感到其管理的實體之間的雙向關係非常有用,而JDO1.0出於各種考慮,暫時沒有將這一點寫進規範中,而只是在JDO2.0中再作規定。這一功能對多對多關係尤其有用。比如我們有兩個類:教師和課程,它們有一個多多對應的關係,一個教師可以教多個課程,而一個課程也可以由多個教師來教,這一關係就是一種多多對應關係。代碼如下:
    public class Teacher {
      String name;
      Set teachingCourses;
    }

    public class Course {
      String title;
      Set byTeachers;
    }
    在這兩個類中,Teachers.teachingCourses與Course.byTeachers是一個雙向的多對多關係,如果我們調用someTeacher.teachingCourses.add(someCourse),那麼someCourse.byTeachers就會包含someTeacher,這一點由JDO去保證,不象JDO1.0要求用戶自己寫代碼與維護這一點。
    在這一點上,目前只有JDOGenie這個產品提供了這一特性,作爲一個廠商擴展功能。
  8. 虛擬機退出時自動關閉PersistenceManagerFactory
    JDO2.0會定義一個具有一定權限保護的方法,允許廠商或者特殊的用戶代碼進行調用,這個方法可以按合理的順序關閉一個PersistenceManagerFactory涉及的各種底層數據庫資源,以防止資源被持久佔用而造成系統漏洞。這樣一來,我們在寫應用程序時就不必考慮過多的清理操作。
    舉例來說,我們寫一個基於JDO的GUI程序,我們可以在一開始就打開一個PersistenceManager,然後在程序中簡單地使用,不用關閉,不用清理相關的查詢結果,當程序退出的時候,底層的JDO可以自動地將涉及到的JDBC資源清理乾淨,不造成資源泄漏。在JDBC應用中,如果採用JDBC打開了一些ResultSet或者Statement資源而不關閉,在程序退出後,這些資源永遠不會得到釋放,最後你再次訪問數據庫時將看到類似“打開的文件句柄超過系統最大數量,不能執行操作”的錯誤信息。
  9. 大小寫敏感的查詢
    當我們對採用字符串提供一個toLowerCase()之類的方法後,實際的查詢將不會受大小寫的影響,達到某些特別的查詢目的。JDO2.0會給出類似的解決方法。
  10. 查詢中的字符串轉換
    在查詢過濾串中將會有一些String(整形值)和String(浮點表達式)之類的類型轉換方法,以提高查詢的靈活性。
  11. 只讀屬性
    一些底層的數據源可能對數據更改有限制,我們將可以在JDO的元數據中對某些類的某些屬性寫上只讀標記,這樣可以在JDO層禁止對該屬性的更改,如果應用中改了這些屬性將得到一個異常。這種機制將盡早地提醒用戶不能更改某些屬性,比數據源級的錯誤提示更有利於排錯和性能優化。
  12. 枚舉模式
    通常,我們會有一些數據是有一定的範圍限制的,比如定單狀態、客戶類型等等,這些數據只會在幾個有限的值只取值,在非數據庫的Java程序中,我們可以採用類常量來表示,但一旦應用到數據庫中,我們不得不做很多檢測和控制來達到這一目的,並且實際存儲的值一般是整數。
    JDO2.0將會對這一常見的功能進行規範化,使我們用JDO一樣能簡單地存儲枚舉數值。比如:我們對定單規定幾個狀態:
    public class OrderStatus {
      private int orderStatus;
      private OrderStatus(int status) { this.orderStatus = status; }

      public static OrderStatus NEW = new OrderStatus(1);
      public static OrderStatus CONFIRMED = new OrderStatus(2);
      public static OrderStatus PAID = new OrderStatus(3);
      public static OrderStatus DELIVERED = new OrderStatus(4);
      public static OrderStatus CLOSED = new OrderStatus(5);
    }
    這樣,我們在其它類中就只能使用order.status = OrderStatus.NEW;之類的語句來設置定單的狀態了,而JDO會自動維護數據庫中的對應值。當然,我們也可以在數據庫中採用字符串來表示狀態值,只須在OrderStatus類中採用一個字符串型的內部屬性,並將構造器改爲字符串參數即可。
  13. 動態內部類的支持
    JDO2.0將支持動態的內部類,其主類也應該是可存儲的,並且在內部類對象與主對象之間會有一個自動實現的多對一關係,這樣一來,我們可以實現一些具有依賴性的數據類型。比如一個客戶對象具有某些高級信息,我們想放到另一個內部類中,可以這樣寫:
    public class Customer {
      String name;
      
      public class Info {
        String idcard;
      }
    }
    這樣,當我們使用new someCustomer.Info();後,JDO會爲someCustomer對象保存一個相關的Info信息。當然,也可以是多個,通過特定的API可以得到某個Customer對象相關的所有Info子類對象。
  14. 對部分屬性的查詢
    在JDO1.0規範中定義的查詢的返回值都是某個類的實例集合,但我們有了EJBQL的經驗後,我們會很想念其中的ejbSelectXXX方法,可以只選取某個類的實例的部分屬性集,這樣可以節省資源,提高性能。JDO2.0會提供類似Query.setResult(String projection)的方法,然後定義一個臨時的類,其中包含對應的屬性,這樣來得到返回的屬性集。
  15. LogWriter支持
    這一功能基本上是爲JDO廠商提供的,讓他們有一個標準的操作日誌輸出方式,不象現在各個廠商輸出自己的SQL調試信息時八仙過海,各顯神通,結果是用戶使用不同產品時得進行不同的設置才能控制這些信息的輸出,麻煩。

  以上就是JDO1.0中提到的將會在2.0規範中定義的內容。此外,個人認爲,還有一些實用的功能也是JDO2.0需要進行規定的,比如動態的類增強,基於SQL92標準的數據庫統計功能等等。

  好了,JDO2.0的啓動已經臨近,讓我們拭目以待,看看JDO2.0將會給我們帶來怎樣的驚喜!同時,我們也祈禱,JDO2.0不會象1.0那樣一團爭論,三年方休!

  本文的版權屬於筆者本人,但歡迎轉載,前提是註明出處和原作者。另外,歡迎在我的專欄中查看我的另幾篇文章,並提出寶貴意見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章