Eclipse快速上手Hibernate--4. 繼承映射(2)
來源:互聯網
上載者:User
繼承 上篇文章《Eclipse快速上手Hibernate--4. 繼承映射(1) 》中已經談了每個類階層一個表(table per class hierarchy)的策略,這篇文章主要說的是每個子類一個表(table per subclass)的策略。一些重複的部分這裡就不說了,請參考上篇文章。 1. 建立項目 · 繼續沿用上篇文章中所建的Java項目:InheritanceMapping。 2. 編寫類檔案 · 建立一個類,包名:javamxj.inheritance.two,類名:Animal。然後在產生的程式碼中添加變數,再利用“產生 Getter 和 Setter”,具體方式同《Eclipse快速上手Hibernate--1. 入門執行個體 》文章中的編輯User.java的方式一樣。· 這個類是父類,只是產生一個簡單的表。
Vehicle.java
/* * Hibernate - 繼承映射(每個子類一個表) * 建立日期 2005-4-9 * @author javamxj(分享java快樂) * @link Blog: htpp://javamxj.mblogger.cn * htpp://blog.csdn.net/javamxj/ */package javamxj.inheritance.two;/** * @hibernate.class */public class Vehicle {private Long id;private String name;/** * @hibernate.id * column="ID" * generator-class="hilo" * unsaved-value="null" */public Long getId() {return id;}public void setId(Long id) {this.id = id;}/** * @hibernate.property * length = "24" */public String getName() {return name;}public void setName(String name) {this.name = name;}}
· 子類Car.javaCar.java
package javamxj.inheritance.two;/** * @hibernate.joined-subclass * @hibernate.joined-subclass-key * column="id" */public class Car extends Vehicle {private String seat;/** * @hibernate.property * column = "載客" * length = "24" */public String getSeat() {return seat;}public void setSeat(String seat) {this.seat = seat;}}
· 子類Truck.javaTruck.java
package javamxj.inheritance.two;/** * @hibernate.joined-subclass * @hibernate.joined-subclass-key * column="id" */public class Truck extends Vehicle {private String load;/** * @hibernate.property * column = "載重" * length = "24" */public String getLoad() {return load;}public void setLoad(String load) {this.load = load;}}
· 這兩個子類都很簡單,注意添加的hibernate.joined-subclass的標記。 · 好了,這時整個項目的結構如下: 3. 運行任務 · 雙擊“generate-hbm”任務,會發現在包中多了一個Vehicle.hbm.xml檔案。如果沒有,按F5鍵重新整理一下(這裡建議開啟Eclipse的“喜好設定”對話方塊,在“工作台”中勾選“自動重新整理工作空間”和“在構建之前自動儲存”這兩項,這樣以後不用每次都重新整理了)。
Vehicle.hbm.xml
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"><hibernate-mapping> <class name="javamxj.inheritance.two.Vehicle" dynamic-update="false" dynamic-insert="false" select-before-update="false" optimistic-lock="version" > <id name="id" column="ID" type="java.lang.Long" unsaved-value="null" > <generator class="hilo"> <!-- To add non XDoclet generator parameters, create a file named hibernate-generator-params-Vehicle.xml containing the additional parameters and place it in your merge dir. --> </generator> </id> <property name="name" type="java.lang.String" update="true" insert="true" access="property" column="name" length="24" /> <!-- To add non XDoclet property mappings, create a file named hibernate-properties-Vehicle.xml containing the additional properties and place it in your merge dir. --> <joined-subclass name="javamxj.inheritance.two.Truck" dynamic-update="false" dynamic-insert="false" > <key column="id" /> <property name="load" type="java.lang.String" update="true" insert="true" access="property" column="載重" length="24" /> </joined-subclass> <joined-subclass name="javamxj.inheritance.two.Car" dynamic-update="false" dynamic-insert="false" > <key column="id" /> <property name="seat" type="java.lang.String" update="true" insert="true" access="property" column="載客" length="24" /> </joined-subclass> </class></hibernate-mapping>
· 重點是看看“joined-subclass”標籤。 · 同時在hibernate.cfg.xml檔案中會自動添加一個對應檔資訊:<mapping resource="javamxj/inheritance/two/Vehicle.hbm.xml"/> · 先運行MySQL,然後雙擊“schemaexport”任務,在項目根目錄下,會更新“schema-export.sql”檔案。開啟這個檔案,會發現添加了以下一些語句。create table Car ( id bigint not null, 載客 varchar(24), primary key (id))create table Truck ( id bigint not null, 載重 varchar(24), primary key (id))create table Vehicle ( ID bigint not null, name varchar(24), primary key (ID)) · 切換到資料庫中,會發現已經自動產生了資料表Car、Truck、Vehicle。 · 將資料表與對應檔Vehicle.hbm.xml對照看看,可以更好的理解每個子類一個表的策略。 4. 測試程式 · 好了,在包javamxj.inheritance.two下建立一個Demo.java類,很簡單,前半部分是添加資料,後半部分是簡單的測試。
Demo.java
/* * Hibernate - 繼承映射(每個子類一個表) * 建立日期 2005-4-9 * @author javamxj(分享java快樂) * @link Blog: htpp://javamxj.mblogger.cn * htpp://blog.csdn.net/javamxj/ */package javamxj.inheritance.two;import java.util.Iterator;import java.util.List;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.Transaction;import net.sf.hibernate.cfg.Configuration;public class Demo {public static void main(String[] args) {try {new Demo();} catch (HibernateException he) {he.printStackTrace();}}public Demo() throws HibernateException {SessionFactory sf = new Configuration().configure().buildSessionFactory();Session sess = sf.openSession();Transaction tx = null;try {tx = sess.beginTransaction();Car car = new Car();car.setName("奇瑞QQ");car.setSeat("4人");sess.save(car);Truck truck = new Truck();truck.setName("一汽解放");truck.setLoad("10噸");sess.save(truck);tx.commit();} catch (HibernateException e) {if (tx != null)tx.rollback();throw e;} finally {sess.close();}sess = sf.openSession();tx = null;try {tx = sess.beginTransaction();List pets = sess.find("from " + Vehicle.class.getName());for (Iterator it = pets.iterator(); it.hasNext();) {Vehicle vehicle = (Vehicle) it.next();System.out.println("車型 " + vehicle.getName()+ " its class is: " + vehicle.getClass().getName());}tx.commit();} catch (HibernateException e) {if (tx != null)tx.rollback();throw e;} finally {sess.close();}}}
· 運行這個類,控制台輸出如下: · 同時,資料表中產生如下資料: 小結: ● 優點:· 與物件導向的概念的一致性最好。對多態的支援最好,對於對象所可能充當的角色僅需要在相應的表中儲存記錄。· 易於修改基類和增加新的類。· 這種映射幾乎有最佳的空間節約性。唯一的容易就是額外的OID,來串連不同的層級層次。 ● 缺點:· 資料庫中存在大量的表。· 訪問資料的時間較長。在讀寫相關的任務上,這種映射方式相當費資源,這個代價還隨著繼承層次的增多而增大。 · 對報表的支援較差,除非定義視圖。 參考:· HIBERNATE - 符合Java習慣的關聯式資料庫持久化(第8章)· Hibernate 簡化繼承映射· Mapping Objects to Relational Databases: O/R Mapping In Detail· Mapping objects to relational databases 下篇文章會談談每個具體類一個表的策略。