本節的范例程序位於配套光盤的sourcecode\chapter14\14.2目錄下,運行該程序前,需要在SAMPLEDB數據庫中手工創建COMPANIES表和EMPLOYEES表,然後加入測試數據,相關的SQL腳本文件為/14.2\schema\sampledb.sql。
在DOS命令行下進入chapter14根目錄,然後輸入命令:
ant -file build2.xml run
就會運行BusinessService類。BusinessService的main()方法調用test()方法,test()方法依次調用以下方法:
findAllHourlyEmployees():檢索數據庫中所有的HourlyEmployee對象。
findAllEmployees():檢索數據庫中所有的Employee對象。
loadCompany():加載一個Company對象。
saveEmployee():保存一個Employee對象。
(1)運行findAllHourlyEmployees()方法,它的代碼如下:
tx = session.beginTransaction();
List results=session.find("from HourlyEmployee");
tx.commit();
return results;
在運行Session的find()方法時,Hibernate執行以下select語句:
select * from EMPLOYEES where EMPLOYEE_TYPE='HE' ;
select * from COMPANIES where ID=1;
在加載HourlyEmployee對象時,還會同時加載與它關聯的Company對象。
(2)運行findAllEmployees()方法,它的代碼如下:
tx = session.beginTransaction();
List results=session.find("from Employee");
tx.commit();
return results;
在運行Session的find()方法時,Hibernate執行以下select語句:
select * from EMPLOYEES;
select * from COMPANIES where ID=1;
在這種映射方式下,Hibernate支持多態查詢,對於從EMPLOYEES表獲得的查詢結果,如果EMPLOYEE_TYPE字段取值為"HE",就創建HoulyEmployee實例,如果EMPLOYEE_TYPE字段取值為"SE",就創建SalariedEmployee實例,這些實例所關聯的Company對象也被加載。
(3)運行loadCompany()方法,它的代碼如下:
tx = session.beginTransaction();
Company company=(Company)session.load(Company.class,new Long(id));
Hibernate.initialize(company.getEmployees());
tx.commit();
這種映射方式支持多態關聯。如果在Company.hbm.xml文件中對employees集合設置了立即檢索策略,那麼Session的load()方法加載的Company對象的employees集合中包含所有關聯的Employee對象。由於本書提供的Company.hbm.xml文件對employees集合設置了延遲檢索策略,因此以上程序代碼還通過Hibernate類的靜態initialize()方法來顯式初始化employees集合。
(4)運行saveEmployee(Employee employee)方法,它的代碼如下:
tx = session.beginTransaction();
session.save(employee);
tx.commit();
在test()方法中,創建了一個HourlyEmployee實例,然後調用saveEmployee()方法保存這個實例:
Employee employee=new HourlyEmployee("Mary",300,company);
saveEmployee(employee);
Session的save()方法能判斷employee變量實際引用的實例的類型,如果employee變量引用HourlyEmployee實例,就執行如下insert語句:
insert into EMPLOYEES(ID,NAME,RATE,EMPLOYEE_TYPE,CUSTOMER_ID)
values(5, 'Mary ',300, 'HE',1);
以上insert語句沒有為SalariedEmployee類的salary屬性對應的SALARY字段賦值,因此這條記錄的SALARY字段為null。