首先是数据库的设计有三种 这里讲述其中一种
数据库设计:
(2)例如:每个子类一张表:一个lorry表,一个salooncar表,父类还有一个basiccar表。
每个类一个数据表,使用 joined-subclass 元素映射继承关系
对于这种设计,父类和子类都需要定义数据表,在子类的数据表中只定义新增的属性,并且父类和子类使用主键来设置它们的关联关系。在映射文件中也定义继承关系的对象映射关系,所以Hibernate能知道这种继承关系,因此支持多态。
这种方式创建的数据表中,子类表的主键也是外键,引用其父类表的主键。
basiccar表只包含父类属性的字段,lorry表和salooncar表只包含子类新增属性的字段。lorry表和salooncar表都以carid字段(可以不同名)作为主键,同时也作为外键关联basic表。这种建表方式,当存储某个车型的数据时,这辆车的父类属性数据先存放在basiccar表中,属于具体车型的子类新增属性数据再存放在对应的子类表中。一辆卡车的完整信息需要id值和carid值相同的basiccar表和lorry表的记录共同组成。
使用这种继承关系的实现方式,Hibernate只需要一个父类的映射文件BasicCar.hbm.xml,映射文件如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="BasicCar" table="basiccar" catalog="test">
<id name="id" type="java.lang.Long">
<column name="id" />
<generator class="increment" />
</id> <property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
<property name="factory" type="java.lang.String">
<column name="factory" length="20" not-null="true" />
</property>
<property name="date" type="java.util.Date">
<column name="date" length="10" not-null="true" />
</property>
<joined-subclass name=“Lorry” table=“lorry”>
<key coloumn = “carid”/>
<property name = “loadweight” column = “loadweight” type =
“java.lang.Double”></property>
</joined-subclass>
<joined-subclass name=“SaloonCar” table=“salooncar”>
<key coloumn = “carid”/>
<property name = “loadpersons” column = “loadpersons” type =
“java.lang.Integer”></property>
</joined-subclass>
</class>
</hibernate-mapping>
由映射文件可知,首先定义BasicCar的属性与字段映射关系,然后通过<joined-subclass>元素定义子类的继承映射。<joined-subclass>元素包含一个<key>子元素,用以声明子类表中既作为主键又作为外键的字段,通过该字段将子类表和父类表关联。这种继承映射支持多态查询。要查找所有的车型数据需执行:List cars = session.find(“from BasicCar”); 相当于同时检索lorry表和salooncar表,并执行与basiccar表的内连接。要查找所有的Lorry车型数据则执行:List cars = session.find(“from Lorry”); 只在Lorry表查询,并执行与basiccar表的内连接。执行内连接是为了获取父类BasicCar的属性数据。保存某个车型执行:BasicCar car = new Lorry(“xxx”, “Shanghai”, Date.valueof(“2016-03-14”), 10); session.save(car); 则父类BasicCar的属性数据存放在父类表中,子类Lorry新增的属性数据存放在子类表中。