Java类中有继承关系,相应的在hibernate中,也有继承关系,子类反应到数据库中,就有多种实现形式了,子类和父类可以映射到同一张表中,子类也可以单独映射成一张表,但是用不同的标签实现,子类表和父类表的关系也不同。在映射文件中,有三个标签可以实现继承关系,分别是:subclass、joined-subclass、union-subclass,先陈述一下这三个标签的区别:
subclass标签就是为子类嵌入父类的表中而设计的,而且要指定鉴别器,即用subclass一定要有判断类型的一个列,鉴别器指定记录属于哪个类型。但是subclass也提供了为子类设置单独的表的功能,即join标签。但是不管是内嵌表还是外部表,都得指定鉴别器。
joined-subclass标签,提供的功能是只能为子类设定外部表,而且没有鉴别器,即子类一张表,父类一张表,子类以父类的主键为外键。父类对应的表中,没有判断类型的列。
注意:这两个标签不能混用,若是只想要内嵌表,或者是既想要有内嵌表,又想要外部表,又或者是只想要外部表,那么只能使用subclass标签,需要注意的是,不论哪种方式,都要指定鉴别器,即父类对应的表中,一定有一个判断类型的列;而若是只想要外部表,又不想在父类对应的表中,要那个判断类型的列,那么只能使用join-subclass
union-subclass是将父类中的属性,添加到子类对应的表中去了。包括父类中的外键。union-class和前两个的区别就在于外键的不同,前两个标签,如果子类有单独对应的表的话,这个表的外键是其父类中的主键,而使用union-class,子类对应的表中的外键则和父类的外键是一样的,因为子类把父类继承的属性,也加到了自己的表当中。这样子类和父类的地位就相当了。不过这不是一种好的理解方式。如果是这样的话,那么就可以把父类设为抽象的类,并且在映射文件中,把父类设置为abstract="true",那么就不会再数据库中生成父类对应的表了,父类就只起到一个抽象的作用了。
下面列举员工和部门的例子说明,假设员工类还有两个子类:一个是技术人员,一个是销售人员:
- public class Employee {
- private int id;
- private String name;
- private Department depart;
- ……//set/get方法
- }
- public class Skiller extends Employee {
- private String skill;
- ……//set/get方法
- }
- public class Saler extends Employee {
- private String sale;
- private int age;
- ……//set/get方法
- }
- public class Department {
- private int id;
- private String name;
- private Set<Employee> emps;
- ……//set/get方法
- }
- <class name="Department">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <set name="emps" inverse="true">
- <key column="depart_id"/>
- <one-to-many class="Employee"/>
- </set>
- </class>
(1)下面关键是员工类的映射文件,我们先来看使用subclass标签的情况:
- <class name="Employee" discriminator-value="0">
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"/><!-- 指定了鉴别器 -->
- <property name="name"/>
- <many-to-one name="depart" column="depart_id"/>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill"/>
- </subclass>
- <subclass name="Saler" discriminator-value="2">
- <property name="sale"/>
- </subclass>
- </class>
- CREATE TABLE `employee` (
- `id` int(11) NOT NULL,
- `type` int(11) NOT NULL,
- `name` varchar(255) DEFAULT NULL,
- `depart_id` int(11) DEFAULT NULL,
- `skill` varchar(255) DEFAULT NULL,
- `sale` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `FK4AFD4ACE972E0614` (`depart_id`),
- CONSTRAINT `FK4AFD4ACE972E0614` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gbk
下面再来看subclass标签的第二种用法:
- <class name="Employee" discriminator-value="0"><!-- discriminator-value="0" -->
- <id name="id">
- <generator class="native"/>
- </id>
- <discriminator column="type" type="int"/><!-- 指定了鉴别器 -->
- <property name="name"/>
- <many-to-one name="depart" column="depart_id"/>
- <subclass name="Skiller" discriminator-value="1">
- <property name="skill"/>
- </subclass>
- <subclass name="Saler" discriminator-value="2">
- <join table="saler">
- <key column="emp_id"/>
- <property name="sale"/>
- </join>
- </subclass>
- </class>
- CREATE TABLE `saler` (
- `emp_id` int(11) NOT NULL,
- `sale` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`emp_id`),
- KEY `FK682490B3F739201` (`emp_id`),
- CONSTRAINT `FK682490B3F739201` FOREIGN KEY (`emp_id`) REFERENCES `employee` (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gbk
(2)joined-subclass的使用
- <class name="Employee"><!-- discriminator-value="0" -->
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <many-to-one name="depart" column="depart_id"/>
- <joined-subclass name="Skiller" table="skiller">
- <key column="emp_id"/>
- <property name="skill"/>
- </joined-subclass>
- <joined-subclass name="Saler" table="saler">
- <key column="emp_id"/>
- <property name="sale"/>
- </joined-subclass>
- </class>
(3)union-subclass的使用
- <class name="Employee">
- <id name="id">
- <generator class="hilo"/>
- </id>
- <property name="name"/>
- <many-to-one name="depart" column="depart_id"/>
- <union-subclass name="Skiller" table="skiller">
- <property name="skill"/>
- </union-subclass>
- <union-subclass name="Saler" table="saler">
- <property name="age"/>
- <property name="sale"/>
- </union-subclass>
- </class>
- CREATE TABLE `skiller` (
- `id` int(11) NOT NULL,
- `name` varchar(255) DEFAULT NULL,
- `depart_id` int(11) DEFAULT NULL,
- `skill` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `FK4AFD4ACE972E06147ffd86be` (`depart_id`),
- CONSTRAINT `FK4AFD4ACE972E06147ffd86be` FOREIGN KEY (`depart_id`) REFERENCES `department` (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gbk