国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

精通Hibernate映射繼承關(guān)系之三

2019-11-18 16:11:50
字體:
供稿:網(wǎng)友

  這種映射方式只需為繼承關(guān)系樹的Employee根類創(chuàng)建一張表EMPLOYEES。如圖14-4所示,在EMPLOYEES表中不僅提供和Employee類的屬性對應(yīng)的字段,還要提供和它的兩個子類的所有屬型對應(yīng)的字段,此外,EMPLOYEES表中需要額外加入一個字符串類型的EMPLOYEE_TYPE字段,用于區(qū)分Employee的具體類型。


精通Hibernate映射繼承關(guān)系之三(圖一)
圖14-4 繼承關(guān)系樹的根類對應(yīng)一個表


Company類和Employee類有相應(yīng)的映射文件,而HourlyEmployee類和SalariedEmployee類沒有相應(yīng)的映射文件。圖14-5顯示了持久化類、映射文件和數(shù)據(jù)庫表之間的對應(yīng)關(guān)系。

精通Hibernate映射繼承關(guān)系之三(圖二)


圖14-5 持久化類、映射文件和數(shù)據(jù)庫表之間的對應(yīng)關(guān)系


14.2.1 創(chuàng)建映射文件

從Company類到Employee類是多態(tài)關(guān)聯(lián),由于關(guān)系數(shù)據(jù)模型描述了Employee類和它的兩個子類的繼承關(guān)系,因此可以映射Company類的employees集合。例程14-5是Company.hbm.xml文件的代碼,該文件不僅映射了Company類的id和name屬性,還映射了它的employees集合。

例程14-5 Company.hbm.xml

<hibernate-mapping ><class name="mypack.Company" table="COMPANIES" ><id name="id" type="long" column="ID"><generator class="increment"/></id><PRoperty name="name" type="string"  column="NAME" /><set name="employees"inverse="true"lazy="true" ><key column="COMPANY_ID" /><one-to-many class="mypack.Employee" /></set>   </class></hibernate-mapping>

Employee.hbm.xml文件用于把Employee類映射到EMPLOYEES表,在這個映射文件中,除了需要映射Employee類本身的屬性,還需要在元素中映射兩個子類的屬性。例程14-6是Employee.hbm.xml文件的代碼。

例程14-6 Employee.hbm.xml



<hibernate-mapping >      <class name="mypack.Employee" table="EMPLOYEES">      <id name="id" type="long" column="ID">        <generator class="increment"/>      </id>      <discriminator column="EMPLOYEE_TYPE" type="string"  />        <property name="name" type="string" column="NAME" />      <many-to-one        name="company"        column="COMPANY_ID"        class="mypack.Company"      />      <subclass name="mypack.HourlyEmployee" discriminator-value="HE" >         <property name="rate" column="RATE" type="double" />      </subclass>      <subclass name="mypack.SalariedEmployee" discriminator-value="SE" >         <property name="salary" column="SALARY" type="double" />      </subclass>           </class>       </hibernate-mapping>           


在Employee.hbm.xml文件中,元素指定EMPLOYEES表中用于區(qū)分Employee類型的字段為EMPLOYEE_TYPE,兩個元素用于映射HourlyEmployee類和SalariedEmployee類,元素的discriminator-value屬性指定EMPLOYEE_TYPE字段的取值。EMPLOYEES表中有以下記錄:


精通Hibernate映射繼承關(guān)系之三(圖三)


其中ID為1和2的記錄的EMPLOYEE_TYPE字段的取值為"HE",因此它們對應(yīng)HourlyEmployee類的實(shí)例,其中ID為3和4的記錄的EMPLOYEE_TYPE字段的取值為"SE",因此它們對應(yīng)SalariedEmployee類的實(shí)例。

這種映射方式要求EMPLOYEES表中和子類屬性對應(yīng)的字段允許為null,例如ID為1和2的記錄的SALARY字段為null,而ID為3和4的記錄的RATE字段為null。如果業(yè)務(wù)需求規(guī)定SalariedEmployee對象的rate屬性不允許為null,顯然無法在EMPLOYEES表中為SALARY字段定義not null約束,可見這種映射方式無法保證關(guān)系數(shù)據(jù)模型的數(shù)據(jù)完整性。

由于HourlyEmployee類和SalariedEmployee類沒有單獨(dú)的映射文件,因此在初始化Hibernate時,只需向Configuration對象中加入Company類和Employee類:

Configuration config = new Configuration();config.addClass(Company.class).addClass(Employee.class);


如果Employee類不是抽象類,即它本身也能被實(shí)例化,那么可以在元素中定義它的discriminator值,形式如下:

<class name="mypack.Employee" table="EMPLOYEES" discriminator-value="EE">


以上代碼表明,如果EMPLOYEES表中一條記錄的EMPLOYEE_TYPE字段的取值為"EE",那么它對應(yīng)Employee類本身的實(shí)例。

14.2.2 操縱持久化對象

這種映射方式支持多態(tài)查詢,對于以下查詢語句:

List employees=session.find("from Employee");


Hibernate會檢索出所有的HourlyEmployee對象和SalariedEmployee對象。此外,也可以單獨(dú)查詢Employee類的兩個子類的實(shí)例,例如:

List hourlyEmployees=session.find("from HourlyEmployee");
本節(jié)的范例程序位于配套光盤的sourcecode/chapter14/14.2目錄下,運(yùn)行該程序前,需要在SAMPLEDB數(shù)據(jù)庫中手工創(chuàng)建COMPANIES表和EMPLOYEES表,然后加入測試數(shù)據(jù),相關(guān)的SQL腳本文件為/14.2/schema/sampledb.sql。

在DOS命令行下進(jìn)入chapter14根目錄,然后輸入命令:


ant  -file  build2.xml  run


就會運(yùn)行BusinessService類。BusinessService的main()方法調(diào)用test()方法,test()方法依次調(diào)用以下方法:

findAllHourlyEmployees():檢索數(shù)據(jù)庫中所有的HourlyEmployee對象。 	findAllEmployees():檢索數(shù)據(jù)庫中所有的Employee對象。 	loadCompany():加載一個Company對象。 	saveEmployee():保存一個Employee對象。


(1)運(yùn)行findAllHourlyEmployees()方法,它的代碼如下:

tx = session.beginTransaction();List results=session.find("from HourlyEmployee");tx.commit();return results;在運(yùn)行Session的find()方法時,Hibernate執(zhí)行以下select語句:select * from EMPLOYEES where EMPLOYEE_TYPE='HE' ;select * from COMPANIES where ID=1;


在加載HourlyEmployee對象時,還會同時加載與它關(guān)聯(lián)的Company對象。

(2)運(yùn)行findAllEmployees()方法,它的代碼如下:

tx = session.beginTransaction();List results=session.find("from Employee");tx.commit();return results;在運(yùn)行Session的find()方法時,Hibernate執(zhí)行以下select語句:
select * from EMPLOYEES;select * from COMPANIES where ID=1;


在這種映射方式下,Hibernate支持多態(tài)查詢,對于從EMPLOYEES表獲得的查詢結(jié)果,如果EMPLOYEE_TYPE字段取值為"HE",就創(chuàng)建HoulyEmployee實(shí)例,如果EMPLOYEE_TYPE字段取值為"SE",就創(chuàng)建SalariedEmployee實(shí)例,這些實(shí)例所關(guān)聯(lián)的Company對象也被加載。

(3)運(yùn)行l(wèi)oadCompany()方法,它的代碼如下:

tx = session.beginTransaction();Company company=(Company)session.load(Company.class,new Long(id));Hibernate.initialize(company.getEmployees());tx.commit();

這種映射方式支持多態(tài)關(guān)聯(lián)。如果在Company.hbm.xml文件中對employees集合設(shè)置了立即檢索策略,那么Session的load()方法加載的Company對象的employees集合中包含所有關(guān)聯(lián)的Employee對象。由于本書提供的Company.hbm.xml文件對employees集合設(shè)置了延遲檢索策略,因此以上程序代碼還通過Hibernate類的靜態(tài)initialize()方法來顯式初始化employees集合。

(4)運(yùn)行saveEmployee(Employee employee)方法,它的代碼如下:



tx = session.beginTransaction();session.save(employee);tx.commit();


在test()方法中,創(chuàng)建了一個HourlyEmployee實(shí)例,然后調(diào)用saveEmployee()方法保存這個實(shí)例:

Employee employee=new HourlyEmployee("Mary",300,company);saveEmployee(employee);


Session的save()方法能判斷employee變量實(shí)際引用的實(shí)例的類型,如果employee變量引用HourlyEmployee實(shí)例,就執(zhí)行如下insert語句:

insert into EMPLOYEES(ID,NAME,RATE,EMPLOYEE_TYPE,CUSTOMER_ID)values(5, 'Mary ',300, 'HE',1);


以上insert語句沒有為SalariedEmployee類的salary屬性對應(yīng)的SALARY字段賦值,因此這條記錄的SALARY字段為null。

(出處:http://www.survivalescaperooms.com)



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 贵德县| 舒兰市| 重庆市| 宁晋县| 兴业县| 微山县| 桐城市| 武宁县| 肇东市| 元阳县| 岚皋县| 东兴市| 沧源| 涿州市| 巴东县| 阳东县| 都匀市| 广西| 南宫市| 碌曲县| 屏山县| 红安县| 遂川县| 辽宁省| 和田市| 台州市| 车险| 鹤壁市| 中西区| 大竹县| 新邵县| 子洲县| 临西县| 精河县| 通州区| 仙桃市| 禄丰县| 托克逊县| 枣强县| 保靖县| 普宁市|