亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

精通Hibernate映射繼承關系之二

2019-11-18 16:11:47
字體:
來源:轉載
供稿:網友

  把每個具體類映射到一張表是最簡單的映射方式。如圖14-2所示,在關系數據模型中只需定義COMPANIES、HOURLY_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類沒有相應的映射文件。圖14-3顯示了持久化類、映射文件和數據庫表之間的對應關系。

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


圖14-2 每個具體類對應一個表


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


圖14-3 持久化類、映射文件和數據庫表之間的對應關系
如果Employee類不是抽象類,即Employee類本身也能被實例化,那么還需要為Employee類創建對應的EMPLOYEES表,此時HE表和SE表的結構仍然和圖14-2中所示的一樣。這意味著在EMPLOYEES表、HE表和SE表中都定義了相同的NAME字段以及參照COMPANIES表的外鍵COMPANY_ID。另外,還需為Employee類創建單獨的Employee.hbm.xml文件。

14.1.1 創建映射文件

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

例程14-1 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" /></class></hibernate-mapping>


HourlyEmployee.hbm.xml文件用于把HourlyEmployee類映射到HE表,在這個映射文件中,除了需要映射HourlyEmployee類本身的rate屬性,還需要映射從Employee類中繼承的name屬性,此外還要映射從Employee類中繼承的與Company類的關聯關系。例程14-2是HourlyEmployee.hbm.xml文件的代碼。

例程14-2 HourlyEmployee.hbm.xml

<hibernate-mapping >      <class name="mypack.HourlyEmployee" 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" />      <many-to-one        name="company"        column="COMPANY_ID"        class="mypack.Company"      />      </class>      </hibernate-mapping>                                                  


 

SalariedEmployee.hbm.xml文件用于把SalariedEmployee類映射到SE表,在這個映射文件中,除了需要映射SalariedEmployee類本身的salary屬性,還需要映射從Employee類中繼承的name屬性,此外還要映射從Employee類中繼承的與Company類的關聯關系。例程14-3是SalariedEmployee.hbm.xml文件的代碼。

例程14-3 SalariedEmployee.hbm.xml

<hibernate-mapping >      <class name="mypack.SalariedEmployee" 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" />      <many-to-one        name="company"        column="COMPANY_ID"        class="mypack.Company"      />      </class>      </hibernate-mapping>         



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

Configuration config = new Configuration();config.addClass(Company.class).addClass(HourlyEmployee.class).addClass(SalariedEmployee.class);



14.1.2 操縱持久化對象

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

List employees=session.find("from Employee");
如果Employee類是抽象類,那么Hibernate會拋出異常。如果Employee類是具體類,那么Hibernate僅僅查詢EMPLOYEES表,檢索出Employee類本身的實例,但不會檢索出它的兩個子類的實例。本節的范例程序位于配套光盤的sourcecode/chapter14/14.1目錄下,運行該程序前,需要在SAMPLEDB數據庫中手工創建COMPANIES表、HE表和SE表,然后加入測試數據,相關的SQL腳本文件為/14.1/schema/sampledb.sql。

在chapter14目錄下有四個ANT的工程文件,分別為build1.xml、build2.xml、build3.xml和build4.xml,它們的區別在于文件開頭設置的路徑不一樣,例如在build1.xml文件中設置了以下路徑:



<property name="source.root" value="14.1/src"/><property name="class.root" value="14.1/classes"/><property name="lib.dir" value="lib"/><property name="schema.dir" value="14.1/schema"/>


在DOS命令行下進入chapter14根目錄,然后輸入命令:

ant  -file  build1.xml  run


就會運行BusinessService類。ANT命令的-file選項用于顯式指定工程文件。BusinessService類用于演示操縱Employee類的對象的方法,例程14-4是它的源程序。

例程14-4 BusinessService.java


public class BusinessService{public static SessionFactory sessionFactory;static{try{Configuration config = new Configuration();config.addClass(Company.class).addClass(HourlyEmployee.class).addClass(SalariedEmployee.class);sessionFactory = config.buildSessionFactory();}catch(Exception e){e.printStackTrace();}}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(employees.iterator());Company company=loadCompany(1);printAllEmployees(company.getEmployees().iterator());Employee employee=new HourlyEmployee("Mary",300,company);saveEmployee(employee);}private void printAllEmployees(Iterator it){while(it.hasNext()){Employee e=(Employee)it.next();if(e instanceof HourlyEmployee){System.out.println(((HourlyEmployee)e).getRate());}elseSystem.out.println(((SalariedEmployee)e).getSalary());}}public static void main(String args[]) throws Exception {new BusinessService().test();sessionFactory.close();}}BusinessService的main()方法調用test()方法,test()方法依次調用以下方法。findAllEmployees():檢索數據庫中所有的Employee對象。loadCompany():加載一個Company對象。saveEmployee():保存一個Employee對象。


(1)運行findAllEmployees()方法,它的代碼如下:

List results=new ArrayList();tx = session.beginTransaction();List hourlyEmployees=session.find("from HourlyEmployee");results.addAll(hourlyEmployees);List salariedEmployees=session.find("from SalariedEmployee");results.addAll(salariedEmployees);tx.commit();return results;


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


select * from HOURLY_EMPLOYEES;select * from COMPANIES where ID=1;


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

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

select * from SALARIED_EMPLOYEES;


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

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

tx = session.beginTransaction();Company company=(Company)session.load(Company.class,new Long(id));List hourlyEmployees=session.find("from HourlyEmployee h where h.company.id="+id);company.getEmployees().addAll(hourlyEmployees);List salariedEmployees=session.find("from SalariedEmployee s where s.company.id="+id);
company.getEmployees().addAll(salariedEmployees);tx.commit();return company;


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

(3)運行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實例,就向HE表插入一條記錄,執行如下insert語句:

insert into HOURLY_EMPLOYEES(ID,NAME,RATE,CUSTOMER_ID)values(3, 'Mary',300,1);


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

(出處:http://www.49028c.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产噜噜噜噜噜久久久久久久久| 欧美日韩福利在线观看| 国产精品久久av| 欧美一级免费看| 中日韩午夜理伦电影免费| 亚洲精品国产拍免费91在线| 亚洲无限乱码一二三四麻| 久久视频这里只有精品| 国产精品精品久久久| 亚洲欧美日韩精品| 国语自产在线不卡| 伊人成人开心激情综合网| 亚洲欧洲av一区二区| 欧美激情按摩在线| 成人写真福利网| 国产精品黄色av| 欧美中文在线免费| 国产精品直播网红| 午夜精品免费视频| 日韩黄色高清视频| 国产成人激情视频| 青青草国产精品一区二区| 精品一区二区电影| 亚洲直播在线一区| 亚洲乱码一区二区| 一区二区亚洲欧洲国产日韩| 国内精品小视频| 国产精品自产拍在线观| 亚洲久久久久久久久久| 亚洲免费伊人电影在线观看av| 久久成人精品电影| 欧美电影免费观看高清| 久久久国产影院| 亚洲日本中文字幕免费在线不卡| 亚洲人成网在线播放| 一区二区三区四区在线观看视频| 成人欧美在线观看| 久久久国产视频91| 国产精品一区二区三区免费视频| 欧美大片网站在线观看| 精品在线观看国产| 欧美性猛交xxxxx水多| 日韩av电影在线免费播放| 欧美激情视频一区二区| 欧美性受xxxx黑人猛交| 国产精品91久久| 亚洲欧美色婷婷| 久久久精品亚洲| 热草久综合在线| 欧美又大粗又爽又黄大片视频| 91在线精品视频| 国产精品美女在线| 日韩精品极品视频免费观看| 国产精品 欧美在线| 91在线直播亚洲| 亚洲成人精品av| 久久99久久99精品免观看粉嫩| 国产精品99蜜臀久久不卡二区| 国产精品va在线播放| 日本久久91av| 91亚洲国产精品| 国产精品久久久久久久久男| 午夜精品一区二区三区在线视| 精品一区二区三区三区| 国产一区二区三区三区在线观看| 日韩av免费看| 成人网页在线免费观看| 精品久久久久久久久久国产| 欧美日韩亚洲网| 日韩av在线精品| 最新的欧美黄色| 91在线无精精品一区二区| 国产精品欧美一区二区三区奶水| 国产99视频精品免视看7| 久久99久久99精品中文字幕| 日韩中文字幕久久| 久久亚洲精品成人| 91国语精品自产拍在线观看性色| 亚洲伊人久久大香线蕉av| 最近2019年手机中文字幕| 精品在线观看国产| 国产精品免费在线免费| 91国产视频在线播放| 亚洲视频在线观看视频| 综合久久五月天| 欧美一级高清免费播放| 国产日韩欧美在线观看| 亚洲成人999| 欧美日韩一二三四五区| 一个人看的www久久| 日韩免费av片在线观看| 深夜福利国产精品| 在线日韩精品视频| 中文字幕精品久久| 亚洲一区中文字幕在线观看| 国产精品久久91| 欧美激情视频一区二区三区不卡| 日韩亚洲精品视频| 国产精品自产拍高潮在线观看| 国产精品久久综合av爱欲tv| 国产69久久精品成人看| 国产高清在线不卡| 欧美成人精品在线观看| 欧美整片在线观看| 久久久日本电影| 日韩精品日韩在线观看| 国产精品444| 中文字幕欧美日韩在线| 日韩影视在线观看| 国产视频在线观看一区二区| 日韩在线观看网址| 日韩在线观看成人| 国产精品日韩在线观看| 国产精品扒开腿做爽爽爽的视频| 国产精品久久久久久久久久ktv| 欧美极品在线视频| 久久精品电影一区二区| 亚洲精品福利免费在线观看| 日韩在线视频免费观看| 国产精品久久久久久亚洲调教| 亚洲电影免费在线观看| 欧美日韩精品在线视频| 亚洲欧美日本伦理| 欧美性感美女h网站在线观看免费| 国产精品久久久久免费a∨大胸| 日韩电影免费在线观看中文字幕| 秋霞av国产精品一区| 久久精品成人欧美大片古装| 日韩av综合网站| 欧美激情视频网址| 亚洲激情视频网| 超碰97人人做人人爱少妇| 国产在线不卡精品| 精品久久在线播放| 久久久久久久久久久人体| 国产中文字幕亚洲| 国产成人亚洲综合青青| 国产一区二中文字幕在线看| 国产视频久久久久| 亚洲欧美成人一区二区在线电影| 日韩精品在线视频观看| 91久久久国产精品| 日韩av在线免费观看| 日韩高清电影免费观看完整版| 欧美综合激情网| 欧美丰满少妇xxxxx| 久久国产精品久久精品| 日韩欧美成人精品| 中文字幕成人精品久久不卡| 日韩国产激情在线| 国产视频亚洲精品| 91久久嫩草影院一区二区| www.亚洲一区| 成人国产亚洲精品a区天堂华泰| 久久国产色av| 欧美国产精品日韩| 欧美性高跟鞋xxxxhd| 亚洲美女精品成人在线视频| 精品一区电影国产| 欧美大秀在线观看| 亚洲高清在线观看| 欧美丰满少妇xxxxx做受| 久久免费视频这里只有精品| 亚洲美女精品成人在线视频|