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

精通Hibernate之映射繼承關系(二)

2013-11-23 20:03:44  來源: Java開源技術 

  把每個具體類映射到一張表是最簡單的映射方式如圖所示在關系數據模型中只需定義COMPANIESHOURLY_EMPLOYEES和SALARIED_EMPLOYEES表為了敘述的方便下文把HOURLY_EMPLOYEES表簡稱為HE表把SALARIED_EMPLOYEES表簡稱為SE表

  HourlyEmployee類和HE表對應HourlyEmployee類本身的rate屬性以及從Employee類中繼承的id屬性和name屬性在HE表中都有對應的字段此外HourlyEmployee類繼承了Employee類與Company類的關聯關系與此對應在HE表中定義了參照COMPANIES表的COMPANY_ID外鍵

  SalariedEmployee類和SE表對應SalariedEmployee類本身的salary屬性以及從Employee類中繼承的id屬性和name屬性在SE表中都有對應的字段此外SalariedEmployee類繼承了Employee類與Company類的關聯關系與此對應在SE表中定義了參照COMPANIES表的COMPANY_ID外鍵

  Company類HourlyEmployee類和SalariedEmployee類都有相應的映射文件而Employee類沒有相應的映射文件顯示了持久化類映射文件和數據庫表之間的對應關系

  

  圖 每個具體類對應一個表

  

  圖 持久化類映射文件和數據庫表之間的對應關系

  如果Employee類不是抽象類即Employee類本身也能被實例化那麼還需要為Employee類創建對應的EMPLOYEES表此時HE表和SE表的結構仍然和圖中所示的一樣這意味著在EMPLOYEES表HE表和SE表中都定義了相同的NAME字段以及參照COMPANIES表的外鍵COMPANY_ID另外還需為Employee類創建單獨的Employeehbmxml文件

   創建映射文件

  從Company類到Employee類是多態關聯但是由於關系數據模型沒有描述Employee類和它的兩個子類的繼承關系因此無法映射Company類的employees集合例程是Companyhbmxml文件的代碼該文件僅僅映射了Company類的id和name屬性

  例程 Companyhbmxml

  

  <hibernatemapping > <class name=mypackCompany table=COMPANIES > <id name=id type=long column=ID> <generator class=increment/> </id> <property name=name type=string column=NAME /> </class> </hibernatemapping>

  HourlyEmployeehbmxml文件用於把HourlyEmployee類映射到HE表在這個映射文件中除了需要映射HourlyEmployee類本身的rate屬性還需要映射從Employee類中繼承的name屬性此外還要映射從Employee類中繼承的與Company類的關聯關系例程是HourlyEmployeehbmxml文件的代碼

  例程 HourlyEmployeehbmxml

  

  <hibernatemapping > <class name=mypackHourlyEmployee table=HOURLY_EMPLOYEES> <id name=id type=long column=ID> <generator class=increment/> </id> <property name=name type=string column=NAME /> <property name=rate column=RATE type=double /> <manytoone name=company column=COMPANY_ID class=mypackCompany /> </class> </hibernatemapping>

  SalariedEmployeehbmxml文件用於把SalariedEmployee類映射到SE表在這個映射文件中除了需要映射SalariedEmployee類本身的salary屬性還需要映射從Employee類中繼承的name屬性此外還要映射從Employee類中繼承的與Company類的關聯關系例程是SalariedEmployeehbmxml文件的代碼

  例程 SalariedEmployeehbmxml

   <hibernatemapping >
      <class name=mypackSalariedEmployee table=SALARIED_EMPLOYEES>
      <id name=id type=long column=ID>
        <generator class=increment/>
      </id>
  
      <property name=name type=string column=NAME />
      <property name=salary column=SALARY type=double />

      <manytoone
        name=company
        column=COMPANY_ID
        class=mypackCompany
      />
      </class>
      </hibernatemapping>

  由於Employee類沒有相應的映射文件因此在初始化Hibernate時只需向Configuration對象中加入Company類HourlyEmployee類和SalariedEmployee類

  Configuration config = new Configuration()

  configaddClass(Companyclass)

  addClass(HourlyEmployeeclass)

  addClass(SalariedEmployeeclass)

   操縱持久化對象

  這種映射方式不支持多態查詢在本書第章的節(多態查詢)介紹了多態查詢的概念對於以下查詢語句

  List employees=sessionfind(from Employee

  為了檢索所有的Employee對象必須分別檢索所有的HourlyEmployee實例和SalariedEmployee實例然後把它們合並到同一個集合中在運行Session的第一個find()方法時Hibernate執行以下select語句

  select * from HOURLY_EMPLOYEES

  select * from COMPANIES where ID=

  從HourlyEmployee類到Company類不是多態關聯在加載HourlyEmployee對象時會同時加載與它關聯的Company對象

  在運行Session的第二個find()方法時Hibernate執行以下select語句

  select * from SALARIED_EMPLOYEES

  從SalariedEmployee類到Company類不是多態關聯在加載SalariedEmployee對象時會同時加載與它關聯的Company對象在本書提供的測試數據中所有HourlyEmployee實例和SalariedEmployee實例都與OID為的Company對象關聯由於該Company對象已經被加載到內存中所以Hibernate不再需要執行檢索該對象的select語句

  ()運行loadCompany()方法它的代碼如下

  

  tx = sessionbeginTransaction(); Company company=(Company)sessionload(Companyclassnew Long(id)); List hourlyEmployees=sessionfind(from HourlyEmployee h where
panyid=+id); companygetEmployees()addAll(hourlyEmployees); List salariedEmployees=sessionfind(from SalariedEmployee s where
panyid=+id); companygetEmployees()addAll(salariedEmployees); mit(); return company;

  由於這種映射方式不支持多態關聯因此由Session的load()方法加載的Company對象的employees集合中不包含任何Employee對象BusinessService類必須負責從數據庫中檢索出所有與Company對象關聯的HourlyEmployee對象以及SalariedEmployee對象然後把它們加入到employees集合中

  ()運行saveEmployee(Employee employee)方法它的代碼如下

  tx = sessionbeginTransaction()

  sessionsave(employee)

  mit()

  在test()方法中創建了一個HourlyEmployee實例然後調用saveEmployee()方法保存這個實例

  Employee employee=new HourlyEmployee(Marycompany)

  saveEmployee(employee)

  Session的save()方法能判斷employee變量實際引用的實例的類型如果employee變量引用HourlyEmployee實例就向HE表插入一條記錄執行如下insert語句

  insert into HOURLY_EMPLOYEES(IDNAMERATECUSTOMER_ID)

  values( Mary

  如果employee變量引用SalariedEmployee實例就向SE表插入一條記錄


From:http://tw.wingwit.com/Article/program/Java/ky/201311/27877.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.