每个子类一个表的方式是将所有的类生成一个表(包括父类),保存子类的时候,同时向父类和子类添加数据,然后把父类中生成的id,保存到子类中,保持关联。在这个主题中我们将先说明这个方法。


一个例子如下:
·  类Vehicle.java

package com.jason.inheritance.two;

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.java

package com.jason.inheritance.two;

public class Car extends Vehicle {
 private String seat;
 public String getSeat() {
  return seat;
 }

 public void setSeat(String seat) {
  this.seat = seat;
 }
}


·  子类Truck.java

package com.jason.inheritance.two;

public class Truck extends Vehicle {
 private String load;
 public String getLoad() {
  return load;
 }

 public void setLoad(String load) {
  this.load = load;
 }
}



·  Vehicle.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.jason.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">
    
   </generator>
  </id>
  
  <property name="name" type="java.lang.String" update="true" insert="true"
   access="property" column="name" length="24"/>
  
  <joined-subclass name="com.jason.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="loads" length="24"/>
   
  </joined-subclass>
  <joined-subclass name="com.jason.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="seat" length="24"/>
   
  </joined-subclass>
  
 </class>
 
</hibernate-mapping>


      显然对应的表是
      vehicle(id, name)        car(id, seat)          truck(id, loads)   
      需要注意的是:car/truck 中的id 和vehicle中的id是一一对应的。    
      /*
      Truck truck = new Truck();
      truck.setName("西风卡车");
      truck.setLoad("10ton");
      sess.save(truck);*/
   插入记录的sql如下:
   Hibernate: insert into Vehicle (name, ID) values (?, ?)
   Hibernate: insert into Truck (loads, id) values (?, ?)
   保存一条truck信息,要先在Vehicle中保存记录,得到id,然后把得到的id和需要的值一同保存到Truck中。


● 优点:
· 与面向对象的概念的一致性最好。对多态的支持最好,对于对象所可能充当的角色仅需要在相应的表中保存记录。
· 易于修改基类和增加新的类。
· 这种映射几乎有最佳的空间节约性。唯一的容易就是额外的OID,来连接不同的层级层次。

● 缺点:
· 数据库中存在大量的表。
· 访问数据的时间较长。在读写相关的任务上,这种映射方式相当费资源,这个代价还随着继承层次的增多而增大。
· 对报表的支持较差,除非定义视图。












参考:

· HIBERNATE - 符合Java习惯的关系数据库持久化(第8章)