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

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

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

    posts - 0, comments - 77, trackbacks - 0, articles - 356
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    EJB學習日記(17)

    Posted on 2007-10-12 10:48 semovy 閱讀(233) 評論(0)  編輯  收藏 所屬分類: EJB

    單個實體BEAN的映射到數(shù)據(jù)庫的方式很簡單,但是如果我們的實體BEAN之間存在著繼承關(guān)系呢?在數(shù)據(jù)庫里面將如何表現(xiàn)這種繼承關(guān)系?
    JAVA持久化規(guī)范里面提供了三種方式去處理繼承實體的映射方式:
    一,所有繼承層次共單獨一張表
    二,每個具體的類一個單獨的表
    三,每個子類一張表

    為了更好的舉例說明,我們構(gòu)造出如下的繼承層次,以做為例子使用。


    我們今天先來看看第一種方式,那就是所有的繼承層次共單獨一張表。

    一,所有繼承層次共單獨一張表

    在這種模式中,一張數(shù)據(jù)庫的表里面將放入所有的繼承層次的類的屬性,在我們的例子中,我們的Person,Customer,Empolyee的實體都將映射在同一張表里面,表的結(jié)構(gòu)如下所示:

     

     

    create table PERSON_HIERARCHY 
     (
       id 
    integer primary key not null,
       firstName 
    varchar(255),
       lastName 
    varchar(255),
       street 
    varchar(255),
       city 
    varchar(255),
       state 
    varchar(255),
       zip 
    varchar(255),
       employeeId 
    integer,
       DISCRIMINATOR 
    varchar(31not null
    );

     

     

    正是因為我們把所有繼承層次的實體都放在同一張表里面,所以我們需要一個來標志具體類型的列,它指示當前記錄是屬于哪個類的,這樣EntityManager好還原成相應的實體BEAN而不致于出錯。我們還是先看看代碼是如何告訴EntityManager它的繼承實現(xiàn)方式的。

     

     

    @Entity
    @Table(name
    ="PERSON_HIERARCHY")
    @Inheritance(strategy
    =InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name
    ="DISCRIMINATOR",
                         discriminatorType
    =DiscriminatorType.STRING)
    @DiscriminatorValue(
    "PERSON")
    public class Person {
       
    private int id;
       
    private String firstName;
       
    private String lastName;

       @Id @GeneratedValue
       
    public int getId( ) { return id; }
       
    public void setId(int id) { this.id = id; }

       
    public String getFirstName( ) { return firstName; }
       
    public void setFirstName(String first) { this.firstName = first; }

       
    public String getLastName( ) { return lastName; }
       
    public void setLastName(String last) { this.lastName = last; }
    }

     

     

     @javax.persistence.Inheritance注釋就是用來聲明繼承的時候它的持久化策略的,它的聲明如下:
     

     

     package javax.persistence;

    @Target(TYPE) @Retention(RUNTIME)
    public @interface Inheritance {
       InheritanceType strategy( ) 
    default SINGLE_TABLE; 

    }

    public enum InheritanceType {
       SINGLE_TABLE, JOINED, TABLE_PER_CLASS
    }

     

     

    在這里,strategy()方法定義了我們所使用的繼承映射模式,我們在這里用的是單獨一張表放所有的繼承層次實體,所以我們使用了枚舉InheritanceType.SINGLE_TABLE,有一點我們需要注意的是,@Inheritance這個注釋僅僅只在繼承層次的根類上是必須要有的,一般它的子類都沒有必要寫這個注釋,除非你想改變繼承映射的實現(xiàn)方式。

     

     

    package javax.persistence;

    @Target(TYPE) @Retention(RUNTIME)
    public @interface DiscriminatorColumn
       String name( ) 
    default "DTYPE";
       DiscriminatorType discriminatorType( ) 
    default STRING;
       String columnDefinition( ) 
    default "";
       
    int length( ) default 10;
    }

     

     

    因為我們使用一張表來保存所有繼承層次的類,所以我們需要一個某種方式好讓持久化實現(xiàn)者知道如何去分辨我們真正想要保存的對象是屬于哪個繼承層次的,我們靠從一個辨別器的列里面去獲得這一點。@javax.persistence.DiscriminatorColumn這個流釋就是指示我們哪個類將會存儲辨別器,看著注釋我們可以知道,這個注釋并不是必要的,因為它每項都有默認值,對于辨別器的類型,默認是String類型,我們除了String類型之外,還可以用如下幾個類型:char,Integer。

     

     

    package javax.persistence;

    @Target(TYPE) @Retention(RUNTIME)
    public @interface DiscriminatorValue {
       String value( )
    }

     

     

    這個注釋是指示我們辨別器的值是多少,這個只是我們提示辨別器的類型是String的時候,還需要我們?nèi)?,如果類型是int或者char的時候,是不需要我們?nèi)ヌ岫ㄋ鼈兊谋鎰e器的值的。所以最好還是使用char或者int類型,以使我們從這些細節(jié)方面解放出來。

    在我們建立了這種映射策略之后,子類的定義就顯得簡單多了:

     

     

    @Entity
    @DiscriminatorValue 
    (
    "CUST")
    public class Customer extends Person {
       
    private String street;
       
    private String city;
       
    private String state;
       
    private String zip;
       
    public String getStreet( ) { return street; }
       
    public void setStreet(String street) { this.street = street; }

    }

     

     

    我們也可以都用默認的值,什么額外的注釋都不要加

     

     

    @Entity
    public class Employee extends Customer {
       
    private int employeeId;

       
    public int getEmployeeId( ) { return employeeId; }
       
    public void setEmployeeId(int id) { employeeId = id; }
    }

     

     

    在這個例子里面,Customer實體的辨別器列的值設為CUST,這是我們?nèi)藶樵O置的。當然我們?nèi)绻辉O置的話,就像Employee,那么它的辨別器列的值就會被設為Employee, 因為它的類的名字就是Employee。

    優(yōu)點:
    SINGLE_TABLE的映射策略是最簡單的實現(xiàn)并且性能來說,也是比其它兩個要高。因為它只有一張表需要去處理。持久化引擎不需要去做任何復雜的連接組合或者子查詢等等,因為所有的的數(shù)據(jù)都存在一張表里面
    缺點:
    這種策略最大的一個缺點就是所有的有關(guān)子類的屬性的映射列都必須是nullable,因為你不可能讓一個類擁有所有的屬性,畢竟這些屬性是所有的類加起來的,所以你不能為你的類加上NOT NULL的約束。還有,因為所有子類的屬性列對于某些實體類來說都是沒有用的,所以SINGLE_TABLE 策略也是不符合規(guī)范的。

    主站蜘蛛池模板: 亚洲天堂2016| 日韩精品无码免费视频| 永久黄网站色视频免费| 特级毛片免费播放| 亚洲综合久久综合激情久久| 歪歪漫画在线观看官网免费阅读| 亚洲av无码成人影院一区| 久久影院亚洲一区| 男男AV纯肉无码免费播放无码| 国产精品亚洲а∨天堂2021 | 青春禁区视频在线观看直播免费 | 永久在线观看免费视频| 色噜噜亚洲男人的天堂| 亚洲精品天堂成人片?V在线播放| 3344永久在线观看视频免费首页| 人成电影网在线观看免费| 国产色在线|亚洲| 国产亚洲av片在线观看16女人 | 一本久到久久亚洲综合| 97免费人妻无码视频| jizz日本免费| 亚洲成av人片在线天堂无| 亚洲AV成人无码久久精品老人| 国产一级一片免费播放| 人禽杂交18禁网站免费| 无码国产精品一区二区免费3p| 色九月亚洲综合网| 亚洲国产91在线| 亚洲第一精品福利| 亚洲综合在线另类色区奇米| 成人免费视频国产| 国内精品免费麻豆网站91麻豆| 成人电影在线免费观看| 亚洲AV色欲色欲WWW| 亚洲 暴爽 AV人人爽日日碰| 久久精品国产亚洲AV麻豆网站 | MM131亚洲国产美女久久| 国产成人免费爽爽爽视频 | 免费国产黄网站在线观看可以下载| 日韩电影免费在线观看网址 | 久久久精品视频免费观看 |