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

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

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

    Sealyu

    --- 博客已遷移至: http://www.sealyu.com/blog

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      618 隨筆 :: 87 文章 :: 225 評論 :: 0 Trackbacks
    因為關系數據庫的表之間不存在繼承關系,Entity 提供三種基本的繼承映射策略:
    每個類分層結構一張表(table per class hierarchy)
    每個子類一張表(table per subclass)
    每個具體類一張表(table per concrete class)

    一、每個類分層結構一張表(table per class hierarchy)
           這種映射方式只需為基類創建一個表即可。在表中不僅提供基類所有屬性對應的字段,還要提供所有子類屬性對應的字段,此外還需要一個字段用于區分子類的具體類型
           要使用每個類分層結構一張表(table per class hierarchy) 策略,需要把@javax.persistence.Inheritance 注釋的strategy屬性設置為InheritanceType.SINGLE_TABLE。除非你要改變子類的映射策略,否則@Inheritance 注釋只能放在繼承層次的基類。通過鑒別字段的值,持久化引掣可以區分出各個類,并且知道每個類對應那些字段。鑒別字段通過@javax.persistence.DiscriminatorColumn 注釋進行定義,name 屬性定義鑒別字段的列名,discriminatorType 屬性定義鑒別字段的類型(可選值有:String, Char, Integer),如果鑒別字段的類型為String 或Char,可以用length 屬性定義其長度。@DiscriminatorValue 注釋為繼承關系中的每個類定義鑒別值,如果不指定鑒別值,默認采用類名
    例:
        @SuppressWarnings("serial")
        @Entity
        @Table(name="Vehicle_Hierarchy")
        @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
        @DiscriminatorColumn(name="Discriminator",
                                             discriminatorType = DiscriminatorType.STRING,
                                             length=30)
        @DiscriminatorValue("Vehicle")
        public class Vehicle implements Serializable{       //基類
        private Long id;
        private Short speed;//速度
        @Id
        @GeneratedValue
        @Column(columnDefinition="integer")//指定使用適配Integer長度的數據類型
        public Long getId() {
        return id;
        }
        public void setId(Long id) {
        this.id = id;
        }

        @SuppressWarnings("serial")
        @Entity
        @DiscriminatorValue("Car")
        public class Car extends Vehicle{        //Vehicle的子類
        private String engine;//發動機
        @Column(nullable=true,length=30)
        public String getEngine() {
        return engine;
        }
        public void setEngine(String engine) {
        this.engine = engine;
            }
        }


         @SuppressWarnings("serial")
         @Entity
         @DiscriminatorValue("Camion")
         public class Camion extends Car{         //Car的子類
         private String container;//集裝箱
         @Column(nullable=true,length=30)
         public String getContainer() {
         return container;
         }
         public void setContainer(String container) {
         this.container = container;
              }
         }
    分析:
           可 以看出,每個子類沒有單獨的映射,在數據庫中沒有對應的表存在。而只有一個記錄所有自身屬性和子類所有屬性的表,在基類為Vehicle 的時候,Discriminator 字段的值將為Vehicle,在子類為Car 的時候,Discriminator 字段的值將為Car,子類為Camion 的時候,Discriminator 字段的值將為Camion。那么,如果業務邏輯要求Car 對象的engine 屬性不允許為null,顯然無法在Vehicle_Hierarchy 表中為engine 字段定義not null 約束,可見這種映射方式無法保證關系數據模型的數據完整性。

    二、每個類分層結構一張表(table per class hierarchy)
           這種映射方式為每個類創建一個表。在每個類對應的表中只需包含和這個類本身的屬性對應的字段,子類對應的表參照父類對應的表,使用每個子類一張表 (table per subclass)策略,需要把@javax.persistence.Inheritance 注釋的strategy 屬性設置為InheritanceType.JOINED

         @SuppressWarnings("serial")
         @Entity
         @Inheritance(strategy=InheritanceType.JOINED)
         @Table(name="Vehicle")
         public class Vehicle implements Serializable{      //基類
         private Long id;
         private Short speed;//速度
         @Id
         @GeneratedValue
         @Column(columnDefinition="integer")
         public Long getId() {
         return id;
         }
         public void setId(Long id) {
         this.id = id;
         }
         public Short getSpeed() {
         return speed;
         }
         public void setSpeed(Short speed) {
         this.speed = speed;
         }
         }

         @SuppressWarnings("serial")
         @Entity
         @Table(name="Car")
         @PrimaryKeyJoinColumn(name="CarID")     //把主鍵對應的列名更改為CarID
         public class Car extends Vehicle{                 //Vehicle的子類
         private String engine;//發動機
         @Column(nullable=true,length=30)
         public String getEngine() {
         return engine;
         }
         public void setEngine(String engine) {
         this.engine = engine;
         }
         }

         @SuppressWarnings("serial")
         @Entity
         @Table(name="Camion")
         @PrimaryKeyJoinColumn(name="CamionID")     //把主鍵對應的列名更改為CamionID
         public class Camion extends Car{                    //Car的子類
         private String container;
         @Column(nullable=true,length=30)
         public String getContainer() {
         return container;
         }
         public void setContainer(String container) {
         this.container = container;
         }
         }
            這種映射方式支持多態關聯和多態查詢,而且符合關系數據模型的常規設計規則。在這種策略中你可以對子類的屬性對應的字段定義not null 約束。該策略的缺點:
            它的查詢性能不如上面介紹的映射策略。在這種映射策略下,必須通過表的內連接或左外連接來實現多態查詢和多態關聯。
    選擇原則:子類屬性非常多,需要對子類某些屬性對應的字段進行not null 約束,且對性能要求不是很嚴格時,優先選擇該策略


    三、每個具體類一張表(table per concrete class)
           這種映射方式為每個類創建一個表。在每個類對應的表中包含和這個類所有屬性(包括從超類繼承的屬性)對應的字段,使用每個具體類一張表(table per concrete class)策略,需要把@javax.persistence.Inheritance 注釋的strategy 屬性設置為InheritanceType.TABLE_PER_CLASS

            注意:一旦使用這種策略就意味著你不能使用AUTO generator 和IDENTITY generator,即主鍵值不能采用數據庫自動生成.

         @SuppressWarnings("serial")
         @Entity
         @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
         @Table(name="Vehicle")
         public class Vehicle implements Serializable{            //基類
         private Long id;
         private Short speed;//速度
         @Id
         @Column(columnDefinition="integer")
         public Long getId() {
         return id;
         }
         public void setId(Long id) {
         this.id = id;
         }
         public Short getSpeed() {
         return speed;
         }
         public void setSpeed(Short speed) {
         this.speed = speed;
         }
         }

         @SuppressWarnings("serial")
         @Entity
         @Table(name="Car")
        public class Car extends Vehicle{               //Vehicle的子類
         private String engine;//發動機
         @Column(nullable=true,length=30)
         public String getEngine() {
         return engine;
         }
         public void setEngine(String engine) {
         this.engine = engine;
         }
         }

         @SuppressWarnings("serial")
         @Entity
         @Table(name="Camion")
         public class Camion extends Car{              //Car的子類
         private String container;//集裝箱
         @Column(nullable=true,length=30)
         public String getContainer() {
         return container;
         }
         public void setContainer(String container) {
         this.container = container;
         }
         }

    注意:在查詢時,例如: from Vehicle v
             查詢所有Vehicle時,因為他是最繼承樹中的根,查詢結果會得到所有繼承于Vehicle類的記錄
    (構造的SQL Where部分:where Discriminator in ('Car', 'Camion'))
             delete from Vehicle v
             執行該操作會刪除自身對應記錄,還會刪除所有繼承Vehicle的記錄,因為他是最繼承樹中的根,就相當于清除整個表的數據

    該策略的優點:
                         在這種策略中你可以對子類的屬性對應的字段定義not null 約束。
    該策略的缺點:
                         不符合關系數據模型的常規設計規則,每個表中都存在屬于基類的多余的字段。同時,為了支持策略的映射,持久化管理者需要決定使用什么方法,一種方法是在 entity 載入或多態關聯時,容器使用多次查詢去實現,這種方法需要對數據庫做幾次來往查詢,非常影響執行效率。另一種方法是容器通過使用SQLUNIOU 查詢來實現這種策略。
    選擇原則:
                         除非你的現實情況必須使用這種策略,一般情況下不要選擇。
    posted on 2009-01-05 14:18 seal 閱讀(1213) 評論(2)  編輯  收藏 所屬分類: Hibernate 、EJB

    評論

    # re: EJB/JPA繼承詳解(轉)[未登錄] 2009-01-06 22:10 x
    復雜。  回復  更多評論
      

    # re: EJB/JPA繼承詳解(轉)[未登錄] 2011-12-20 16:21 無名
    @x
    而且不知哪種更好一些  回復  更多評論
      

    主站蜘蛛池模板: 精品无码AV无码免费专区| 亚洲AV无码国产一区二区三区| 国产在线精品一区免费香蕉| 亚洲不卡AV影片在线播放| 特级毛片免费观看视频| 亚洲国产精品人人做人人爽| 亚洲精品视频免费| 国产啪亚洲国产精品无码| 久草免费福利在线| 亚洲s色大片在线观看| 在线观看免费av网站| 亚洲天堂中文字幕在线观看| 青青草免费在线视频| 亚洲人成色在线观看| 波多野结衣免费视频观看 | 国产麻豆一精品一AV一免费| 亚洲AV午夜福利精品一区二区| 18禁黄网站禁片免费观看不卡| 亚洲精品123区在线观看| 国产精品jizz在线观看免费| 男女猛烈无遮掩视频免费软件 | 亚洲AV永久青草无码精品| 91久久精品国产免费一区| 久久亚洲精品国产亚洲老地址 | 精品免费久久久久久成人影院| WWW国产亚洲精品久久麻豆| 亚洲国产精品成人久久蜜臀 | 精品成在人线AV无码免费看| 亚洲男同gay片| 国产gv天堂亚洲国产gv刚刚碰| 一级毛片在线观看免费| 在线精品亚洲一区二区| 色噜噜亚洲精品中文字幕| 最近中文字幕高清免费中文字幕mv| 亚洲色成人四虎在线观看| 中文字幕不卡亚洲| 国产免费一区二区三区| 日韩在线视频播放免费视频完整版| 亚洲国产天堂久久综合网站| 午夜免费福利网站| 久久免费视频观看|