日期:2014-05-16 浏览次数:20597 次
现实世界中有很多种动物,比如:Pig(猪),Bird(鸟)等等,当我用面向对象的思想分析时,我们一般会将它们的共同部分抽取出来增加一个抽象类Animal(动物),这样在编写程序时Pig和Bird只需要继承它们的父类Animal就可以省去很多重复的代码。Java代码中只需要extends关键字就可以轻松实现这种继承关系,但是对于我们使用的关系型数据库是没有任何关键字可以指明这种继承关系的。为了将这种继承关系反映到数据库中,Hibernate为我们提供了3种解决方案:
1、 每个具体类对应一张表
该方案是使继承体系中每一个具体的类都对应数据库中的一张表。示意图如下:
每个子类对应的数据库表都包含了父类的信息,并且还有自己独有的属性,每个子类对应一张表,这个表具备完整的信息,包含了所有父类继承下来的属性映射的字段,这种策略是使用<union-subclass>标签来定义子类的。
注意:在保存对象的时候id不能重复(不能使用数据库的自增方式生成主键)
部分代码展示:
<?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 package="com.hibernate"> <class name="Animal" table="t_animal" abstract="true"> <id name="id"> <generator class="assigned"/> </id> <property name="name"/> <property name="sex"/> <union-subclass name="Pig" table="t_pig"> <property name="weight"/> </union-subclass> <union-subclass name="Bird" table="t_bird"> <property name="height"/> </union-subclass> </class> </hibernate-mapping>
2、 每个类一张表
这种策略是使用<joined-subclass>标签来定义子类的。父类、子类都对应一张数据库表。在父类对应的数据库表中,它存储了所有记录的公共信息,实际上该父类对应的表会包含所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字段。子类对应的数据表与父类对应的数据表,通过一对一主键关联的方式关联起来。
这种策略的示意图:
t_animal表中存储了子类的所有记录,但只记录了他们共有的信息,而他们独有的信息存储在他们对应的表中,一条记录要获得其独有的信息,要通过t_animal记录的主键到其对应的子表中查找主键值一样的记录然后取出它独有的信息。
注意:Joined-subclass标签的name属性是子类的全路径名
Joined-subclass标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来关联的。如:<key column=”PARENT_KEY_ID”/>,这里的column,实际上就是父类的主键对应的映射字段名称。
Joined-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平 行。 当Joined-subclass标签的定义与class标签平行的时候,需要在Joined-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在joined-subclass标签的内部。
部分代码展示:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-