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

          EJB學(xué)習(xí)日記(19)

          Posted on 2007-10-12 10:49 semovy 閱讀(314) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): EJB

          繼承映射策略之----每個(gè)子類(lèi)一張表

          在每個(gè)子類(lèi)一張表的映射策略中,每一個(gè)子類(lèi)都有一張屬于自己的表,但是這張表只包括了定義在這個(gè)子類(lèi)上面的屬性而已,定義在它的父類(lèi)的屬性它的表里面是沒(méi)有的,所以這樣的方式映射的話,就不會(huì)浪費(fèi)一點(diǎn)資源了,每一張表,每一列都是不可少的,也不會(huì)出現(xiàn)冗余。這種格式是有點(diǎn)像TABLE_PER_CLASS的策略,只不過(guò)這種方案是規(guī)范的,沒(méi)有像TABLE_PER_CLASS一樣重復(fù)定義列,在這里我們叫它JOINED策略。

          按我們的例子,這種策略映射出來(lái)的話,數(shù)據(jù)庫(kù)的結(jié)構(gòu)將如下所示:

           

          create table Person (
             id 
          integer primary key not null,
             firstName 
          varchar(255),
             lastName 
          varchar(255),
          );

          create table Customer (
             id 
          integer primary key not null,
             street 
          varchar(255),
             city 
          varchar(255),
             state 
          varchar(255),
             zip 
          varchar(255),
          );

          create table Employee (
             EMP_PK 
          integer primary key not null,
             employeeId 
          integer
          );

           

          當(dāng)持久化管理器加載一個(gè)類(lèi)或者查詢一個(gè)子類(lèi)的時(shí)候,它必須要對(duì)數(shù)據(jù)庫(kù)做連接動(dòng)作,所以我們必須要保存這幾張表有一個(gè)能夠彼此連接起來(lái)的列。在我們的例子里面,EMPLOYEE, CUSTOMER, 和 PERSON表共享同樣的主鍵值,這種策略的注釋也是挺簡(jiǎn)單的:

           

          @Entity
          @Inheritance(strategy
          =InheritanceType.JOINED)
          public class Person {

          }

          @Entity
          public class Customer extends Person {

          }

          @Entity
          @PrimaryKeyJoinColumn 
          (name
          ="EMP_PK")
          public class Employee extends Customer {

          }

           

          在持久化的時(shí)候,持久化管理器需要知道每一張表用哪一列來(lái)進(jìn)行連接,所以當(dāng)我們要指定某一列的時(shí)候,就可以用如下注釋?zhuān)?/p>

           @javax.persistence.PrimaryKeyJoinColumn,它的聲明如下:
           

           package javax.persistence;

          @Target({TYPE, METHOD, FIELD})
          public @interface PrimaryKeyJoinColumn
             String name( ) 
          default "";
             String referencedColumnName( ) 
          default "";
             String columnDefinition( ) 
          default "";
          }

           

          name()方法提出你此表中需要用來(lái)連接的列的名字,它默認(rèn)是與父類(lèi)的主鍵進(jìn)行連接,當(dāng)我們不想與父類(lèi)的主鍵進(jìn)行連接時(shí),我們可以用referencedColumnName( )這個(gè)方法來(lái)指定你要連接父類(lèi)的哪個(gè)具體的列,它可以被定義為父類(lèi)的任意列,但是默認(rèn)是連接父類(lèi)的主鍵列,如果從父類(lèi)到子類(lèi)的主鍵名都是一樣的,那么這個(gè)屬性就沒(méi)必要再設(shè)了,因?yàn)镃ustomer和Person的主鍵是一樣的,所以在Customer里面不需要定義任何額外的屬性,一切默認(rèn)就可以了,但是由于Employee里面的主鍵名和其它的不一樣,所以它必須顯式地聲明它的主鍵是哪一個(gè)。如果有的類(lèi)有復(fù)合主鍵,那么可以用這個(gè)注釋?zhuān)?br /> @javax.persistence.PrimaryKeyJoinColumns

           

          package javax.persistence;

          @Target({TYPE, METHOD, FIELD})
          public @interface PrimaryKeyJoinColumns {
             @PrimaryKeyJoinColumn[] value( );
          }

           

          它包括了多個(gè)@PrimaryKeyJoinColumn的注釋。

          注意:有些持久化實(shí)現(xiàn)這種策略會(huì)需要一個(gè)辨別器列,雖然大部份是不需要的,所以最好是在使用前查看一下你的持久化提供商的實(shí)現(xiàn)說(shuō)明。

          優(yōu)點(diǎn):
          這種策略雖然沒(méi)有SINGLE_TABLE策略的速度快,但是你可以定義任何的非空約束在任何的表里面,并且這種模式是規(guī)范化的。
          缺點(diǎn):
          唯一的缺點(diǎn)就是沒(méi)有SINGLE_TABLE 策略的性能好。

          到現(xiàn)在我們?nèi)N處理繼承映射的策略都說(shuō)完了,在不同的場(chǎng)合和環(huán)境下選擇不同的映射策略是最明智的選擇,沒(méi)有一種策略可以勝任所有場(chǎng)合,否則的話,出一種就可以了,干嘛還出三種呢。希望大家在實(shí)際工作中選出適合自己的映射策略,更好的提高工作效率。

          主站蜘蛛池模板: 龙南县| 南乐县| 周宁县| 镇江市| 广昌县| 于田县| 甘南县| 钦州市| 阿坝县| 九龙县| 沁阳市| 固安县| 泰兴市| 景宁| 绥宁县| 磐石市| 渝中区| 延庆县| 莱州市| 天柱县| 安吉县| 九龙县| 镇安县| 阜城县| 佳木斯市| 西贡区| 迁安市| 闽清县| 固始县| 安龙县| 潼关县| 精河县| 昌平区| 阿合奇县| 宜阳县| 吉林市| 江源县| 卓资县| 弥渡县| 修武县| 沁阳市|