<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    love fish大鵬一曰同風起,扶搖直上九萬里

    常用鏈接

    統計

    積分與排名

    friends

    link

    最新評論

    EJB3.0之介紹Entity(轉)

    EJB3介紹:Overview

    EJB作為企業級的數據訪問/持久化標準在1999年作為J2EE規范的核心規范出現,極大的轉變了java企業級開發的模式,為java軟件開發提供了一個良好的架構。 EJB從1.0到2.1在J2EE架構中,都是作為一個服務器端的(Server side)的數據訪問中間件。開發人員通過EJB標準的API接口來訪問操作數據,避免直接用JDBC和Sql操作底層的數據庫。

    采用EJB架構的目標在于:

    • 減輕直接操作底層數據庫的工作量
    • 為企業級開發引入了面向對象/面向服務的開發架構
    • 數據對象生命周期的自動管理
    • 分布式能力
    • 集成/聲明式的安全/事務管理

    在舊的EJB模型中(2.1以前),EJB實現了大部分的目標,但一個巨大的缺陷是原有的模型在試圖減輕數據訪問工作量的同時也引入了更多的復雜開發需求。 例如EJB核心的的Entity Bean必須特定的Home,Remote,Business接口,發布前需要預編譯,只能實現單表映射操作,靜態的EJB-QL(EJB查詢語言)都不能滿足簡化數據庫操作的目標。 EJB 2.1的復雜度,開發成本和性能問題使得EJB在問世4年后仍然等不到廣泛的應用。

    到了2004年,隨著POJO( Plain Old Java Object )模型的出現,動態代碼操作,IOC模式等先進,簡單實用技術的發展和它們在各種獨立產品中的表現,都證明POJO,IOC的技術比原有的EJB 2.1模型更適合作為數據訪問中間件,開發的難度和成本遠遠小于目前的EJB模型,確有更靈活和可擴展。 2004年9月J2EE平臺規范集眾家所長,推出了跨越式的Java EE 5.0規范,最核心的是全面引入新的基于POJO和IOC技術的EJB3模型。到此,J2EE 5規范( Java EE 5 )成為一個集大成者,納百家之長,成為java企業開發統一的標準規范。

    EJB 3和EJB 2.1的區別

    從整個EJB規范的角度來說,EJB 3和EJB 2.1最大變更在Entity Bean持久化API上。在EJB3中,Entity Bean持久化已經單獨作為一個Persistence API規范和其他的EJB部分分離開來。下面我們主要討論EJB 3和EJB 2.1在持久化API上的區別。

    EJB 2.1模型存在復雜度高的缺陷:

    • EJB 2.0 模型要求創建多個組件接口并實現多個不必要的回調方法
    • 組件接口要求實現 EJBObject 或 EJBLocalObject 以及處理許多不必要的異常
    • 基于XML的EJB 2.0 部署描述符比較復雜并容易出錯
    • 基于 EJB 模型的容器管理持久性在開發和管理方面過于復雜,并且失去了幾個基本特性--如使用數據庫序列定義主鍵的標準方法
    • EJBQL 語法非常有限,而且是靜態的,無法做到運行期間的動態查詢
    • EJB 2.0 組件并非是真正面向對象的,因為它們在繼承和多態性方面的有使用限制
    • 開發人員無法在 EJB 容器外部測試 EJB 模塊,而在容器內部調試 EJB非常復雜和耗時
    • 查找和調用 EJB 2.0 是一項復雜的任務。即使是在應用程序中使用最基本的 EJB 也需要對 JNDI 有一個詳細的了解
    • 對容器的依賴使得EJB 2.0只能用于服務器組件的開發,無法實現一次編寫,四處運行的面向構件的開發
    所有這些復雜度和缺陷,都導致EJB 2.0的采用無法真正簡化開發并提高生產力。

    EJB 3.0 旨在解決以往EJB 2.0 模型的復雜性和提高靈活性,具體體現在:

    • 消除了不必要的接口Remote, Home, EJB以及回調方法實現
    • 實體Bean采用了POJO模型,一個簡單的java bean就可以是一個Entity Bean。無需依賴容器運行和測試
    • 全面采用O/R Mapping技術來實現數據庫操作
    • 實體Bean可以運用在所有需要持久化的應用,不管是客戶端還是服務器端。從而真正實現面向構件的開發
    • 實體 bean 現在支持繼承和多態性
    • 靈活豐富的EJB3查詢語言
    • SQL支持
    • 使用元數據批注代替部署描述符,減少復雜配置和提高可維護性
    • 將常規 Java 類用作 EJB 并將常規業務接口用于 EJB

    EJB 3中的元數據批注:Annotation

    EJB3 規范中引入了元數據批注(Annotation)。Annotation是從J2SE 1.5開始稱為java語言的一部分。Annotation并不是一個新的事物,在J2SE 1.5以前,人們已經自行引入了象著名的XDoclet等外掛式的元數據批注方法。而在.NET中,元數據批注也早已經是C#語言的成分了。

    在以往,我們都是采用xml作為配置批注,但采用文本的xml配置存在一些缺陷:

    • 描述符多,不容易記憶和掌握
    • 無法做自動的校驗,需要人工排錯
    • 當系統變大時,大量的xml配置難以管理
    • 讀取和解析xml配置非常耗時,導致應用啟動緩慢,不利于測試和維護
    • 做O/R Mapping的時候需要在java文件和xml配置文件之間交替,增大了工作量
    • 運行中保存xml配置需要消耗額外的內存

    采用元數據可以很好的解決這些問題:

    • 描述符大量減少。以往在xml配置中往往需要描述java屬性的類型,關系等等。而元數據本身就是java語言,從而省略了大量的描述符
    • 編譯期校驗。錯誤的批注在編譯期間就會報錯。
    • 元數據批注在java代碼中,避免了額外的文件維護工作
    • 元數據被編譯成java bytecode,消耗小的多內存,讀取也非常迅速,往往比xml配置解析快幾個數據量級,利于測試和維護

    第一個Entity Bean:HelloWorld

    EJB3中的Entity Bean是如此的簡單,就是一個普通的java bean加上一些精煉的元數據批注。

                    
    @Entity
    @Table( name="helloTable" )
    public class HelloEntityBean {
    
        private int id;
        private String foo;
    
        /**
         * The entity class must have a no-arg constructor.
         */
        public HelloEntityBean() {
        }
    
        public HelloEntityBean(int id, String foo) {
            this.id = id;
            this.foo = foo;
        }
    
        @Id(generate=GeneratorType.NONE)
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getFoo() {
            return foo;
        }
    
        public void setFoo(String foo) {
            this.foo = foo;
        }
    
        public String toString(){
            return "HelloEntityBean: id=" + id + ", foo=" + foo;
        }
    }
                    
                

    代碼中元數據的說明:

    @Entity :EJB3 Entity Bean的批注,表明當前的java bean作為一個Entity Bean來處理。

    @Table( name="helloTable" ) :顧名思義,定義當前Entity對應數據庫中的表。

    @Id(generate=GeneratorType.NONE) :我們把HelloEntityBean的id屬性定義為主鍵。主鍵產生策略為GeneratorType.NONE,意味這是一個業務主鍵。

    就這么簡單!

    解說Entity

    從EJB3.0開始,Entity Bean持久化規范與EJB的其他規范如Session Bean, Message Driven Bean和EJB3容器規范開始分離,單獨作為一個持久化API。而在將來,該持久化API很可能會從EJB3.0規范中脫離出來成為一個獨立的規范Java Persistence API。作為Java平臺上的通用數據訪問標準接口。 為了跟規范一致,我們將在開發手冊中將Entity Bean稱為Entity。

    雖然EJB3 Entity可以是很簡單的java bean,只要批注了@Entity或者在xml配置中作了說明,就被做一個可持久化的Entity處理。 但還是需要遵行一定的規則:

    • Entity類必須要有一個無參數的public或者protected的Constructor。
    • 如果在應用中需要將該Entity類分離出來在分布式環境中作為參數傳遞,該Entity Class需要實現java.io.Serialzable接口。
    • Entity類不可以是final,也不可有final的方法。
    • abstract類和Concrete實體類都可以作為Entity類。
    • Entity類中的屬性變量不可以是public。Entity類的屬性必須通過getter/setter或者其他的商業方法獲得。

    定義對Entity中屬性變量的訪問

    在絕大部分的商業應用,開發人員都可以忽略這部分無需關心。但如果你需要編寫復雜的Entity類的話,你需要了解這個部分。復雜的Entity類是指在Entity類的getter/setter和商業方法中包含比較復雜的業務邏輯而不是僅僅返回/符值某個屬性。

    在大部分的情況下,我們都建議使Entity類中setter/getter中的邏輯盡可能簡單,除了必要的校驗符值外,不要包含復雜的業務邏輯,例如對關聯的其他Entity類進行操作。但有些情況下,我們還是需要在Entity類的setter/getter方法中包含商業邏輯。這時候,采用何種屬性訪問方式就可能會影響代碼的性能甚至是邏輯正確產生影響。

    EJB3持久化規范中,在默認情況下所有的屬性都會自動的被持久化,除非屬性變量用@Transient元數據進行了標注。針對可持久化屬性定義了兩種屬性訪問方式(access): FIELD和PROPERTY。

    • 如果采用access=FIELD, EJB3 Persistence運行環境(EJB3持久化產品,如Liberator EJB3)直接訪問對象的屬性變量,而不是通過getter。這種訪問方式也不要求每個屬性必須有getter/setter。如果需要在getter中包含商業邏輯,應該采用access=FIELD的方式。
    • 如果采用access=PROPERTY, EJB3 Persistence運行環境將通過Entity類上的getter來訪問對象的屬性變量,這就要求每個屬性變量要有getter/setter方法。在EJB3中,默認的屬性訪問方式是PROPERTY。access=PROPERTY時getter/setter的邏輯應該盡量簡單。

    規范中access方式還有多一層含義。就是采用access=FIELD時,元數據應該批注在屬性上。

                    
        @Id(generate=GeneratorType.NONE)
        private int id;
        private String foo;
    
        /**
         * The entity class must have a no-arg constructor.
         */
        public HelloEntityBean() {
        }
    
        
        public int getId() {
            return id;
        } 
                

    采用access=PROPERTY(默認方式)時,元數據應該批注在對應屬性變量的getter上。

                         
        private int id;
        private String foo;
    
        /**
         * The entity class must have a no-arg constructor.
         */
        public HelloEntityBean() {
        }
    
        @Id(generate=GeneratorType.NONE)
        public int getId() {
            return id;
        } 
                     

    為了方便開發,Liberator EJB3實現對元數據批注的位置比規范規定的寬松,針對屬性變量或它的getter進行批注都可以,不受access類型的影響。

    對Entity類中,getter/setter的命名規則遵從java bean規范。

    Entity類中的屬性變量可以是以下數據類型:

    • 原始數據類型和他們的對象類型
    • java.lang.String
    • java.math.BigInteger
    • java.math.BigDecimal
    • java.util.Date
    • java.util.Calendar
    • java.sql.Date
    • java.sql.Time
    • java.sql.Timestamp
    • byte[]
    • Byte[]
    • char[]
    • Character[]
    • enums
    • Entity類
    • 嵌入實體類(embeddable classes)

    還可以是以下集合類型:

    • java.util.Collection和它的實體類
    • java.util.Set和它的實體類
    • java.util.List和它的實體類
    • java.util.Map和它的實體類

    主鍵和實體標識(Primary Key and Entity Identity)

    每個Entity類都必須有一個主鍵。在EJB3中定義了兩種主鍵:

    • 鍵單主鍵
    • 復合主鍵

    簡單主鍵必須對應Entity中的一個屬性變量(Instance Variable),而該屬性對應數據庫表中的一列。使用簡單主鍵,我們只需要用@Id元數據對一個屬性變量或者她的getter方法進行批注。

    當我們需要使用一個或多個屬性變量(表中的一列或多列)聯合起來作為主鍵,我們需要使用復合主鍵。復合主鍵要求我們編寫一個復合主鍵類( Composite Primary Key Class )。復合主鍵類需要符合以下一些要求:

    • 復合主鍵類必須是public和具備一個沒有參數的constructor
    • 復合主鍵類的每個屬性變量必須有getter/setter,如果沒有,每個屬性變量則必須是public或者protected
    • 復合主鍵類必須實現java.io.serializable
    • 復合主鍵類必須實現equals()和hashcode()方法
    • 復合主鍵類中的主鍵屬性變量的名字必須和對應的Entity中主鍵屬性變量的名字相同
    • 一旦主鍵值設定后,不要修改主鍵屬性變量的值
    一起看一個復合主鍵的例子。Entity類Person,它的主鍵屬性變量是firstName和lastName。
                    
        @Id
        private String firstName;
        
        @Id
        private String lastName;
    
        public Person() {
        }
       
        
        
                
    Person的復合主鍵類:
                    
    public class PersonPK implements java.io.Serializable{
        
        private String firstName;
        private String lastName;
    
        public PersonPK() {
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof PersonPK)) return false;
    
            final PersonPK personPK = (PersonPK) o;
    
            if (!firstName.equals(personPK.firstName)) return false;
            if (!lastName.equals(personPK.lastName)) return false;
    
            return true;
        }
    
        public int hashCode() {
            int result;
            result = firstName.hashCode();
            result = 29 * result + lastName.hashCode();
            return result;
        }
    }                
                    

    posted on 2006-07-03 00:57 liaojiyong 閱讀(1143) 評論(0)  編輯  收藏 所屬分類: EJB

    主站蜘蛛池模板: 99久久久国产精品免费牛牛| a级毛片黄免费a级毛片| 男女免费观看在线爽爽爽视频| 日本激情猛烈在线看免费观看| 日韩毛片无码永久免费看| 亚洲女女女同性video| 成年人免费网站在线观看| 亚洲精品无码成人| 国产又大又黑又粗免费视频 | 国产乱子精品免费视观看片| 亚洲国产精品成人久久久| 亚州免费一级毛片| 午夜在线a亚洲v天堂网2019| 免费精品一区二区三区在线观看| 亚洲第一综合天堂另类专| 国产一级一片免费播放| 国产精品无码免费专区午夜| 亚洲国产精品一区二区成人片国内| 四虎影视成人永久免费观看视频| 亚洲国产精品婷婷久久| 黄色网址免费观看| 精品无码专区亚洲| 亚洲人成网亚洲欧洲无码久久| 免费精品无码AV片在线观看| 亚洲香蕉在线观看| 免费在线观看黄色毛片| 中文字幕无码一区二区免费| 亚洲大尺码专区影院| 国产极品粉嫩泬免费观看 | 成年人在线免费看视频| 美女扒开尿口给男人爽免费视频| 亚洲伊人久久成综合人影院| 日韩中文字幕免费视频| 亚洲精品无码久久久久A片苍井空| 亚洲精品网站在线观看不卡无广告| 成人精品一区二区三区不卡免费看| 亚洲无限乱码一二三四区| 国产成人3p视频免费观看 | 国产免费av片在线看| www免费插插视频| 亚洲欧洲日产国码在线观看|