继承关系
hibernate的继承关系有三种,分别是:
说明 | 优点 | 缺点 | |
subclass | 父类子类保存在同一张表,通过一个辨别字段区分类型。 | 所有数据都保存在一张表,性能略高。 | 存在多余的字段。字段必须允许为null。 |
joined-subclass | 父类子类相同的字段保存在同一张表,子类独有的字段存在另一张表。 | 不存在多余的字段。 | 需要维护的表的数量增多。 |
union-subclass | 父类子类都有独立的表。 | 关系清晰明确。 | 有多余的字段,操作时候需要维护多张表,性能不高。 |
介绍完三种关系后,一个一个的进行测试。
首先来看看subclass是如何实现继承关系的。下面是两个类person和student的代码,student继承了person,并且添加了一个school属性:
package cn.net.bysoft.model1;
public class Person {
// getter and setter
private int id;
private String name;
}
package cn.net.bysoft.model1;
public class Student extends Person {
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
private String school;
}
接下来是*.hbm.xml配置文件,使用了discriminator辨别类型节点,并且在class节点中加入了discriminator-value属性,具体来看下配置文件:
<?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">
<hibernate-mapping>
<class name="cn.net.bysoft.model1.Person" table="PERSON" discriminator-value="PERSON">
<id name="id" type="integer" column="ID">
<!-- 指定主键的生成方式,native是使用数据库本地的方式 -->
<generator class="native"></generator>
</id>
<!-- 辨别字段 -->
<discriminator column="TYPE" type="string"></discriminator>
<property name="name" type="string" column="NAME"></property>
<subclass name="cn.net.bysoft.model1.Student" discriminator-value="STUDENT">
<property name="school" type="string" column="SCHOOL"></property>
</subclass>
</class>
</hibernate-mapping>
测试一个save方法,看一看生成的数据表:
@Test
public void testSubClassSave() {
Person person = new Person();
person.setName("Jack");
Student student = new Student();
student.setName("XiaoMing");
student.setSchool("Two");
session.save(person);
session.save(student);
}
在看看joined-subclass,对象不用改变,save方法也不用修改,只修改一下配置文件即可,不在需要辨别类型,直接加入joined-subclass节点:
<?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">
<hibernate-mapping>
<class name="cn.net.bysoft.model1.Person" table="PERSON">
<id name="id" type="integer" column="ID">
<!-- 指定主键的生成方式,native是使用数据库本地的方式 -->
<generator class="native"></generator>
</id>
<property name="name" type="string" column="NAME"></property>
<joined-subclass name="cn.net.bysoft.model1.Student" table="STUDENT">
<key column="STUDENT_ID"></key>
<property name="school" type="string" column="SCHOOL"></property>
</joined-subclass>
</class>
</hibernate-mapping>
最后看一下union-subclass是如何配置的,直接修改配置文件:
<?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">
<hibernate-mapping>
<class name="cn.net.bysoft.model1.Person" table="PERSON">
<id name="id" type="integer" column="ID">
<!-- 指定主键的生成方式,native是使用数据库本地的方式 -->
<generator class="hilo"></generator>
</id>
<property name="name" type="string" column="NAME"></property>
<union-subclass name="cn.net.bysoft.model1.Student" table="STUDENT">
<property name="school" type="string" column="SCHOOL"></property>
</union-subclass>
</class>
</hibernate-mapping>
这里注意,使用union-subclass时,父类的主键生成方式不能是native。