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

精通Hibernate之映射繼承關系三

2013-11-23 20:38:21  來源: Java開源技術 

  <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類是抽象類那麼Hibernate會拋出異常如果Employee類是具體類那麼Hibernate僅僅查詢EMPLOYEES表檢索出Employee類本身的實例但不會檢索出它的兩個子類的實例本節的范例程序位於配套光盤的sourcecode\chapter\目錄下運行該程序前需要在SAMPLEDB數據庫中手工創建COMPANIES表HE表和SE表然後加入測試數據相關的SQL腳本文件為\\schema/sampledbsql
  
  在chapter目錄下有四個ANT的工程文件分別為buildxmlbuildxmlbuildxml和buildxml它們的區別在於文件開頭設置的路徑不一樣例如在buildxml文件中設置了以下路徑
  
  <property name=sourceroot value=/src/>
  <property name=classroot value=/classes/>
  <property name=libdir value=lib/>
  <property name=schemadir value=/schema/>
  
  在DOS命令行下進入chapter根目錄然後輸入命令
  
  ant file buildxml run
  
  就會運行BusinessService類ANT命令的file選項用於顯式指定工程文件BusinessService類用於演示操縱Employee類的對象的方法例程是它的源程序
  
  例程 BusinessServicejava
  
  public class BusinessService{
  public static SessionFactory sessionFactory;
  static{
  try{
  Configuration config = new Configuration();
  configaddClass(Companyclass)
  addClass(HourlyEmployeeclass)
  addClass(SalariedEmployeeclass);
  sessionFactory = configbuildSessionFactory();
  }catch(Exception e){eprintStackTrace();}
  }
  
  public void saveEmployee(Employee employee) throws Exception{……}
  public List findAllEmployees() throws Exception{……}
  public Company loadCompany(long id) throws Exception{……}
  
  public void test() throws Exception{
  List employees=findAllEmployees();
  printAllEmployees(erator());
  
  Company company=loadCompany();
  printAllEmployees(companygetEmployees(erator());
  
  Employee employee=new HourlyEmployee(Marycompany);
  saveEmployee(employee);
  
  }
  
  private void printAllEmployees(Iterator it){
  while(ithasNext()){
  Employee e=(Employee)itnext();
  if(e instanceof HourlyEmployee){
  Systemoutprintln(((HourlyEmployee)e)getRate());
  }else
  Systemoutprintln(((SalariedEmployee)e)getSalary());
  }
  }
  public static void main(String args[]) throws Exception {
  new BusinessService()test();
  sessionFactoryclose();
  }
  }
  BusinessService的main()方法調用test()方法test()方法依次調用以下方法
  findAllEmployees()檢索數據庫中所有的Employee對象
  loadCompany()加載一個Company對象
  saveEmployee()保存一個Employee對象
  
  ()運行findAllEmployees()方法它的代碼如下
  
  List results=new ArrayList();
  tx = sessionbeginTransaction();
  List hourlyEmployees=sessionfind(from HourlyEmployee);
  resultsaddAll(hourlyEmployees);
  
  List salariedEmployees=sessionfind(from SalariedEmployee);
  resultsaddAll(salariedEmployees);
  
  mit();
  return results;
  
  為了檢索所有的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/28808.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.