为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了3中方案:
- 一个具体子类对应一张表(每个子类对应一张表,父类无表)
- 使用一张表表示所有继承体系下的类的属性的并集(整个继承体系一张表,通过类型区分)
- 每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来(父类、子类都有表,使用主键关联)
1、实体对象
1.1 父类实体(Person类)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo.entity; /** * 人实体(父类) * @author Don * @date:日期:2017年4月11日 时间:下午4:08:04* * @version 1.0 */ public class Person { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
1.2 子类实体(Student类)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo.entity; import java.util.HashSet; import java.util.Set; /** * 学生实体(子类) * @author Don * @date:日期:2017年4月11日 时间:下午2:25:15* * @version 1.0 */ public class Student extends Person { private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; } }
1.3 子类实体(Teacher类)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo.entity; /** * 教师实体(子类) * @author Don * @date:日期:2017年4月11日 时间:下午4:11:08* * @version 1.0 */ public class Teacher extends Person { private String jobTitle; public String getJobTitle() { return jobTitle; } public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; } }
2、数据库关系映射配置
2.1 父类无表关系配置
<?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> <!-- name:实体, table:表名 --> <!-- 每个具体子类对应一张表,试用<union-subclass>标签,abstract为true时标识父类无表 --> <class name="demo.entity.Person" abstract="true"> <!-- name:主键的名字,column:主键数据库表列,identity自增 --> <id name="Id"> <!-- 生成主键--> <generator class="uuid"></generator> </id> <!-- name:实体中的属性名,length:长度 ,column:表中的字段(实体属性和字段一致可省略),type:类型(可不写由hiberbate自动匹配) --> <property name="name" /> <union-subclass name="demo.entity.Student" table="ex_student" extends="demo.entity.Person"> <property name="code"></property> </union-subclass> <union-subclass name="demo.entity.Teacher" table="ex_teacher" extends="demo.entity.Person"> <property name="jobTitle"></property> </union-subclass> </class> </hibernate-mapping>
2.2 整个体系一张表关系配置
<?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> <!-- name:实体, table:表名 --> <!-- 使用一张表表示所有继承体系下的类的属性的并集,使用<discriminator>--> <class name="demo.entity.Person" table="ex_person"> <!-- name:主键的名字,column:主键数据库表列,identity自增 --> <id name="Id"> <!-- 生成主键--> <generator class="uuid"></generator> </id> <!-- name:实体中的属性名,length:长度 ,column:表中的字段(实体属性和字段一致可省略),type:类型(可不写由hiberbate自动匹配) --> <property name="name" /> <!-- 会在ex_person表中生成一个字段,用来标记记录属于哪一个子类 --> <discriminator column="personType" type="string"></discriminator> <subclass name="demo.entity.Student" discriminator-value="stu"> <property name="code"></property> </subclass> <subclass name="demo.entity.Student" discriminator-value="tea"> <property name="jobTitle"></property> </subclass> </class> </hibernate-mapping>
2.3 每个类都有表,使用主键关联联系配置
<?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> <!-- name:实体, table:表名 --> <!-- 使用一张表表示所有继承体系下的类的属性的并集,使用<discriminator>--> <class name="demo.entity.Person" table="ex_person"> <!-- name:主键的名字,column:主键数据库表列,identity自增 --> <id name="Id"> <!-- 生成主键--> <generator class="uuid"></generator> </id> <!-- name:实体中的属性名,length:长度 ,column:表中的字段(实体属性和字段一致可省略),type:类型(可不写由hiberbate自动匹配) --> <property name="name" /> <joined-subclass name="demo.entity.Student" table="ex_student"> <!-- 对应学生表的主键Id --> <key column="stuid"></key> <property name="code"></property> </joined-subclass> <joined-subclass name="demo.entity.Teacher" table="ex_teacher"> <!-- 对应学生表的主键Id --> <key column="teaid"></key> <property name="jobTitle"></property> </joined-subclass> </class> </hibernate-mapping>
3、 测试数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package demo.test; import org.hibernate.classic.Session; import demo.entity.Person; import demo.entity.Teacher; import demo.entity.Student; import demo.util.HibernateUtil; public class TestSave { public static void main(String[] args) { Session session = HibernateUtil.getCurrentSession(); session.beginTransaction(); Student student = new Student(); student.setName("Don"); student.setCode("091449"); Teacher teacher = new Teacher(); teacher.setName("张三"); teacher.setJobTitle("高级教师"); session.save(student); session.save(teacher); //查询(查询学生姓名,有继承关系未指定学生对象,使用其父对象查询) Person person =(Person)session.get(Person.class, "2c918c7b5b5c1adc015b5c1ae1cb0001"); System.out.println(person.getName()); System.out.println(person.getClass().getName()); session.getTransaction().commit(); } }