熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Hibernate的繼承關系

2013-11-23 20:31:16  來源: Java開源技術 

每個子類對應一個數據表(Table per concrete class)
 
學生表
    create table `sample``student`(
        `id` bigint not null auto_increment
       `name` varchar() default not null
       `score` float
        primary key (`id`)
    );
    create unique index `PRIMARY` on `sample``student`(`id`);
教師表
    create table `sample``teacher`(
        `id` bigint not null auto_increment
       `name` varchar() default not null
       `salary` float()
        primary key (`id`)
    );
    create unique index `PRIMARY` on `sample``teacher`(`id`);
 
Person抽象基類
public abstract class Person implements javaioSerializable {
    private Long id;
    private String name;
 
    /**defaultconstructor*/
    public Person() {
    }
 
    public Long getId() {
       returnthisid;
    }
    publicvoid setId(Long id) {
       thisid = id;
    }
    public String getName() {
       returnthisname;
    }
    publicvoid setName(String name) {
       thisname = name;
    }
}
 
子類分別實現它並添加額外的屬性和相應gettter和setter方法
如Student類
public class Student extends Person {
    private Float score;
 
    public Student() {
       super();
    }
    public Float getScore() {
       returnscore;
    }
    publicvoid setScore(Float score) {
       thisscore = score;
    }
}
 
hibernatecfgxml
<?xml version= encoding=UTF?>
<!DOCTYPE hibernateconfiguration PUBLIC
          //Hibernate/Hibernate Configuration DTD //EN
         configurationdtd>
<hibernateconfiguration>
 
    <sessionfactory>
       <property name=connectionusername>root</property>
       <property name=connectionurl>
           jdbc:mysql://localhost:/sample
       </property>
       <property name=dialect>
           orghibernatedialectMySQLDialect
       </property>
       <property name=connectionpassword></property>
       <property name=connectiondriver_class>
           commysqljdbcDriver
       </property>
       <property name=show_sql>true</property>
       <property name=current_session_context_class>thread</property>
 
       <mapping resource=powerwind/bean/Studenthbmxml />
       <mapping resource=powerwind/bean/Teacherhbmxml />
 
    </sessionfactory>
</hibernateconfiguration>
 
由於Person抽象類沒有對應數據庫的表也沒有對應的映射文件在HQL查詢中也就不支持多態查詢感覺上Person抽象類的作用只是減少JAVA代碼的編寫而已
每個類對應一個表(Table per subclass)
人員表
create table `sample``person`(
        `id` bigint not null auto_increment
       `name` varchar()
        primary key (`id`)
    );
學生表
create table `sample``student`(
        `id` bigint default not null
       `score` float
        primarykey (`id`)
    );
教師表
create table `sample``teacher`(
        `id` bigint default not null
       `salary` float
        primary key (`id`)
    );
 
兩個子類的實現和前一種完全一樣 Person類也只是去掉abstract修飾符而已映射文件只需要Personhbmxml一個即可
 
<hibernatemapping>
    <class name=powerwindbeanPerson table=person
       catalog=sample>
       <id name=id type=javalangLong>
           <column name=id />
           <generator class=native></generator>
       </id>
       <property name=name type=javalangString>
           <column name=name length= notnull=true />
       </property>
      
       <joinedsubclass name=powerwindbeanStudent
           table=student>
           <key column=id />
           <property name=score type=javalangFloat>
              <column name=score precision= scale= />
           </property>
       </joinedsubclass>
      
       <joinedsubclass name=powerwindbeanTeacher
           table=teacher>
           <key column=id />
           <property name=salary type=javalangFloat>
              <column name=salary precision= scale= />
           </property>
       </joinedsubclass>
    </class>
</hibernatemapping>
這種方式是支持多態查詢的
多態查詢語句Query query=sdaogetSession()createQuery(from Person);
 
一個表對多個類(Table per class hierarchy)
人員表
    create table `sample``person`(
        `id` bigint not null auto_increment
       `name` varchar()
       `score` float
       `salary` float
       `type` char()
        primary key (`id`)
    );
Personhbmxml
<hibernatemapping>
    <class name=powerwindbeanPerson table=person
       catalog=sample>
       <id name=id type=javalangLong>
           <column name=id />
           <generator class=native></generator>
       </id>
       <discriminator column=type type=javalangString />
       <property name=name type=javalangString>
           <column name=name length= notnull=true />
       </property>
      
       <subclass name=powerwindbeanStudent
           discriminatorvalue=S>
           <property name=score type=javalangFloat />
       </subclass>
      
       <subclass name=powerwindbeanTeacher
           discriminatorvalue=T>
           <property name=salary type=javalangFloat />
       </subclass>
    </class>
</hibernatemapping>
優點是單表查詢支持多態缺點是要在表增加字段(type)用於區分子類
附加實體粒度設計
面向設計的細粒度
人員表
    create table `sample``person`(
        `id` bigint not null auto_increment
       `name` varchar()
       `email` varchar()
       `phone` varchar()
        primary key (`id`)
    );
Person類
publicclass Person implements javaioSerializable {
    private Long id;
    private String name;
    private Contact contact;
}
Contact類
publicclass Contact implements javaioSerializable {
    private String email;
    private String phone;
}
以上兩個類的代碼省略了getter和setter方法
Personhbmxml
<hibernatemapping>
    <class name=powerwindbeanPerson table=person
       catalog=sample>
       <id name=id type=javalangLong>
           <column name=id />
           <generator class=native></generator>
       </id>
       <property name=name type=string column=name/>
      
       <component name=contact class=powerwindbeanContact>
           <property name=email type=string column=email/>
           <property name=phone type=string column=phone/>
       </component>
    </class>
</hibernatemapping>
這樣的細粒度有什麼用呢?應該在處理比較復雜表結構才體現出來吧
 
面向性能的細粒度
假如Contact類包含的字段是重量級的數據如圖片之類而我們一般可能只需要一些簡單的信息摘要要怎麼做呢?
 
    create table `sample``person`(
        `id` bigint not null auto_increment
       `name` varchar()
`gender` varchar()
       `email` varchar()
       `phone` varchar()
        primary key (`id`)
    );
首先定義個基類BasePerson
publicclass BasePerson {
    private Long id;
    private String name;
}
 
Person類繼承BasePerson類添加多一個gender屬性
PersonDetail類繼承Person類添加多一個email和phone屬性
Personhbmxml
    <class name=powerwindbeanPerson table=person
       catalog=sample>
       <id name=id type=javalangLong>
           <column name=id />
           <generator class=native></generator>
       </id>
       <property name=name type=string column=name/>
       <property name=gender type=string column=gender/>
    </class>
PersonDetailhbmxml
    <class name=powerwindbeanPersonDetail table=person
       catalog=sample polymorphism=explicit>
       <id name=id type=javalangLong>
           <column name=id />
           <generator class=native></generator>
       </id>
       <property name=name type=string column=name />
       <property name=gender type=string column=gender />
       <property name=phone type=string column=phone />
       <property name=email type=string column=email />
    </class>
 
除了polymorphism=explicit這一句和每個子類對應一個數據表的繼承關系沒有什麼區別正是這句設置去除了對PersonDetail的隱式多態查詢
       Query query=getSession()createQuery(from Person);
       Query query=getSession()createQuery(from PersonDetail);
上面兩句中第一句並不會查詢到PersonDetail 對象即查詢字段不包括email和phone
 


參考《深入淺出hibernate》一書


From:http://tw.wingwit.com/Article/program/Java/ky/201311/28608.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.