为了将程序领域中的继承关系反映到数据中,Hibernate为我们提供了3中方案:

  1. 一个具体子类对应一张表(每个子类对应一张表,父类无表)
  2. 使用一张表表示所有继承体系下的类的属性的并集(整个继承体系一张表,通过类型区分)
  3. 每个子类使用一张表只存储它特有的属性,然后与父类所对应的表以一对一主键关联的方式关联起来(父类、子类都有表,使用主键关联)

1、实体对象

1.1 父类实体(Person类)

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;
    }
    
}
View Code

1.2 子类实体(Student类)

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;
    }
}
View Code

1.3 子类实体(Teacher类)

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;
    }
}
View Code

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、 测试数据

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();

    }

}
View Code
posted on 2017-04-11 17:03  zxd543  阅读(730)  评论(0编辑  收藏  举报