posts - 14,  comments - 37,  trackbacks - 0

          POJO = pure old java object or plain ordinary java object or what ever.

          PO = persisent object 持久對象

          就是說在一些Object/Relation Mapping工具中,能夠做到維護數據庫表記錄的persisent object完全是一個符合Java Bean規范的純Java對象,沒有增加別的屬性和方法。全都是這樣子的:

           1public class User {    
           2  private long id;    
           3  private String name;   
           4  public void setId(long id) {   
           5 this.id = id;   
           6}
               
           7public void setName(String name) {   
           8this.name=name;   
           9}
              
          10 public long getId() {   
          11 return id;   
          12}
               
          13public String getName() {    
          14return name;   
          15}
             
          16}
               
          17

          ---------------------------------------------------------------------------
          首先要區別持久對象和POJO。

          持久對象實際上必須對應數據庫中的entity,所以和POJO有所區別。比如說POJO是由new創建,由GC回收。但是持久對象是insert 數據庫創建,由數據庫delete刪除的?;旧铣志脤ο笊芷诤蛿祿烀芮邢嚓P。另外持久對象往往只能存在一個數據庫Connection之中, Connnection關閉以后,持久對象就不存在了,而POJO只要不被GC回收,總是存在的。

          由于存在諸多差別,因此持久對象PO(Persistent Object)在代碼上肯定和POJO不同,起碼PO相對于POJO會增加一些用來管理數據庫entity狀態的屬性和方法。而ORM追求的目標就是要 PO在使用上盡量和POJO一致,對于程序員來說,他們可以把PO當做POJO來用,而感覺不到PO的存在。

          JDO的實現方法是這樣的:
          1、編寫POJO
          2、編譯POJO
          3、使用JDO的一個專門工具,叫做Enhancer,一般是一個命令行程序,手工運行,或者在ant腳本里面運行,對POJO的class文件處理一下,把POJO替換成同名的PO。
          4、在運行期運行的實際上是PO,而不是POJO。

          該方法有點類似于JSP,JSP也是在編譯期被轉換成Servlet來運行的,在運行期實際上運行的是Servlet,而不是JSP。

          Hibernate的實現方法比較先進:
          1、編寫POJO
          2、編譯POJO
          3、直接運行,在運行期,由Hibernate的CGLIB動態把POJO轉換為PO。

          由此可以看出Hibernate是在運行期把POJO的字節碼轉換為PO的,而JDO是在編譯期轉換的。一般認為JDO的方式效率會稍高,畢竟是編 譯期轉換嘛。但是Hibernate的作者Gavin King說CGLIB的效率非常之高,運行期的PO的字節碼生成速度非常之快,效率損失幾乎可以忽略不計。

          實際上運行期生成PO的好處非常大,這樣對于程序員來說,是無法接觸到PO的,PO對他們來說完全透明??梢愿幼杂傻囊訮OJO的概念操縱PO。 另外由于是運行期生成PO,所以可以支持增量編譯,增量調試。而JDO則無法做到這一點。實際上已經有很多人在抱怨JDO的編譯期Enhancer問題 了,而據說JBossDO將采用運行期生成PO字節碼,而不采用編譯期生成PO字節碼。

          另外一個相關的問題是,不同的JDO產品的Enhancer生成的PO字節碼可能會有所不同,可能會影響在JDO產品之間的可移植性,這一點有點類似EJB的可移植性難題。

          -----------------------------------------------------------------------------------
          由這個問題另外引出一個JDO的缺陷。

          由于JDO的PO狀態管理方式,所以當你在程序里面get/set的時候,實際上不是從PO的實例中取values,而是從JDO StateManager中取出來,所以一旦PM關閉,PO就不能進行存取了。

          在JDO中,也可以通過一些辦法使得PO可以在PM外面使用,比如說定義PO是transient的,但是該PO在PM關閉后就沒有PO identity了。無法進行跨PM的狀態管理。

          而Hibernate是從PO實例中取values的,所以即使Session關閉,也一樣可以get/set,可以進行跨Session的狀態管理。

          在分多層的應用中,由于持久層和業務層和web層都是分開的,此時Hibernate的PO完全可以當做一個POJO來用,也就是當做一個VO,在 各層間自由傳遞,而不用去管Session是開還是關。如果你把這個POJO序列化的話,甚至可以用在分布式環境中。(不適合lazy loading的情況)

          但是JDO的PO在PM關閉后就不能再用了,所以必須在PM關閉前把PO拷貝一份VO,把VO傳遞給業務層和web層使用。在非分布式環境中,也可 以使用ThreadLocal模式確保PM始終是打開狀態,來避免每次必須進行PO到VO的拷貝操作。但是不管怎么說,這總是權宜之計,不如 Hibernate的功能強。

          posted on 2007-07-10 09:30 冰封的愛 閱讀(152) 評論(0)  編輯  收藏 所屬分類: J2EE
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          留言簿(3)

          隨筆檔案

          文章分類

          文章檔案

          相冊

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 南郑县| 伊吾县| 内丘县| 九江县| 岳西县| 伊金霍洛旗| 高阳县| 通城县| 黎平县| 芷江| 长垣县| 临邑县| 咸丰县| 栾川县| 宿迁市| 潜山县| 高邑县| 娱乐| 思南县| 通城县| 颍上县| 综艺| 股票| 宜章县| 临江市| 都匀市| 望奎县| 略阳县| 勃利县| 富源县| 交口县| 安化县| 民乐县| 穆棱市| 富民县| 托里县| 上虞市| 株洲市| 沅陵县| 玉林市| 凯里市|