继承关系映射

三种继承关系映射:

  1. subclass:只有一张表,此表有一个辨别者字段,用来分别每一条记录是父类,还是子类,同时子类的字段属性不允许为空

  2. joined-subclass:有两张表,父类一张表,拥有父类的所有属性对应的字段,子类一张表,拥有子类独有的属性对应的字段,没有继承下来的父类的属性对应的字段,子类表的主键同时外键引用父类表的主键,当插入一个子类记录时,同时向父类表和子类表插入记录

  3. union-subclass:有两张表,父类一张表,拥有父类的所有属性对应的字段,子类一张表,拥有子类的所有属性对应的字段以及继承父类的所有属性对应的字段,当插入一个子类记录时,只向子类那张表插入记录

首先是两个实体Bean, Person类与子类Student

Person类

//人
public class Person {
    //主键ID
    private Integer id;
    private String name;
    private int age;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

Student类

//学生
public class Student extends Person{
    //学生独有的字段
    private String school;

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }
}

下面是三种继承关系映射

  1. subclass

    Person的XML配置文件:Person.hbm.xml

<?xml version="1.0"?> 
     <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<!-- 

        注意:记录类型是Person类型或是Student类型由辨别者列的字段值决定 

          1:在<class>节点中配置discriminator-value="person"属性, 
            说明名此记录为person类型 
          2:在<subclass>节点中配置discriminator-value="student"属性, 
               说明名此记录为student类型 
-->

<hibernate-mapping package="entity6">
    <!-- discriminator-value="person" : 插入Person记录时,
          辨别者列的字段值为person 
    -->
    <class name="Person" table="persons" discriminator-value="person">
        <id name="id" type="java.lang.Integer">
            <!-- name:表中的序列名 -->
            <column name="id" />
            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
            <generator class="native" />
        </id>

        <!-- 配置辨别者列 -->
        <discriminator column="type" type="string"></discriminator>

        <property name="name" type="java.lang.String">
            <column name="name" />
        </property>

        <property name="age" type="int">
            <column name="age" />
        </property>

        <!-- 映射Student子类 -->
        <!-- discriminator-value="student" : 插入Person记录时,
              辨别者列的字段值为student 
        -->
        <subclass name="Student" discriminator-value="student">
            <property name="school" type="string" column="school"></property>
        </subclass>

    </class>
</hibernate-mapping>

下面是HibernateTest测试

    /**
     * subclass缺点:
     * 1. 使用了辨别者列
     * 2. 子类独有的字段不能添加非空约束
     * 3. 若继承层次比较深的话,则数据表的字段也比较多
     */


    //增
    @Test
    public void test1(){
        /**
         * 插入操作:
         * 1. 对于子类对象只需把记录插入到一张数据表中
         * 2. 辨别者列由Hibernate自动维护,不需要人为插入该字段值
         */

        //一条Person记录
        Person person = new Person();
        person.setName("person");
        person.setAge(20);

        //一条Student记录
        Student student = new Student();
        student.setName("student");
        student.setAge(22);
        student.setSchool("school");

        //保存
        session.save(person);
        session.save(student);
    }

    //查
    @Test
    public void test2(){
        /**
         * 1. 查询父类记录,只需查询一张表
         * 2 .查询子类记录,只需查询一张表
         */

        //查询条件中"FROM Person"  - Person不是表名,是类名!
        List<Person> persons = session.createQuery("FROM Person").list();
        System.out.println(persons.size());

        //查询条件中"FROM Student"  - Student不是表名,是类名!
        List<Student> students = session.createQuery("FROM Student").list();
        System.out.println(students.size());
    }
  1. joined-subclass

    Person的XML配置文件:Person.hbm.xml

<?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="entity7">
    <class name="Person" table="persons">
        <id name="id" type="java.lang.Integer">
            <!-- name:表中的序列名 -->
            <column name="id" />
            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
            <generator class="native" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="name" />
        </property>

        <property name="age" type="int">
            <column name="age" />
        </property>

        <!-- 新建一张表存放子类   table="students" 表名:students -->
        <joined-subclass name="Student" table="students">
            <!-- 
                key :此表的主键ID,同时外键引用Person的主键ID 
                column="" : 字段名
            -->
            <key column="student_id"></key>
            <property name="school" type="string" column="school"></property>
        </joined-subclass>
    </class>
</hibernate-mapping>

下面是HibernateTest测试

    /**
     * joined-subclass优点:
     * 1. 不需要使用了辨别者列
     * 2. 子类独有的字段能添加非空约束
     * 3. 没有冗余的字段
     */


    //增
    @Test
    public void test1(){
        /**
         * 插入操作:
         * 1. 对于子类对象需要插入到两张表中
         */

        //一条Person记录
        Person person = new Person();
        person.setName("person");
        person.setAge(20);

        //一条Student记录
        Student student = new Student();
        student.setName("student");
        student.setAge(22);
        student.setSchool("school");

        //保存
        session.save(person);
        session.save(student);
    }

    //查
    @Test
    public void test2(){
        /**
         * 1. 查询父类记录,做一个左外连接查询
         * 2 .查询子类记录,做一个内连接查询
         */

        //查询条件中"FROM Person"  - Person不是表名,是类名!
        List<Person> persons = session.createQuery("FROM Person").list();
        System.out.println(persons.size());

        //查询条件中"FROM Student"  - Student不是表名,是类名!
        List<Student> students = session.createQuery("FROM Student").list();
        System.out.println(students.size());
    }
  1. union-subclass

    Person的XML配置文件:Person.hbm.xml

<?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="entity8">
    <class name="Person" table="persons">
        <id name="id" type="java.lang.Integer">
            <!-- name:表中的序列名 -->
            <column name="id" />
            <!-- 主键的生成方式 不能使用native -->
            <generator class="hilo" />
        </id>

        <property name="name" type="java.lang.String">
            <column name="name" />
        </property>

        <property name="age" type="int">
            <column name="age" />
        </property>

        <!-- 
            union-subclass继承关系映射:
                1. 新建一张表,此表有Person的所有字段(主键除外)
                2. 此表还有Student独有的字段
                3. table="":新建表的表名
        -->     
        <union-subclass name="Student" table="students">
            <!-- 
                Student类独有的字段生成
                name="":Student类中的属性名
                column="":数据表的字段名
                type="":字段的数据类型
            -->
            <property name="school" column="school" type="string"></property>
        </union-subclass>
    </class>
</hibernate-mapping>

下面是HibernateTest测试

    /**
     * union-subclass
     * 优点:
     * 1. 不需要使用了辨别者列
     * 2. 子类独有的字段能添加非空约束
     *
     * 缺点:
     * 1. 存在冗余的字段
     * 2. 若更新父表的字段,更新效率较低
     */


    //增
    @Test
    public void test1(){
        /**
         * 插入操作:
         * 1. 对于子类对象只需要插入到一张表中
         */

        //一条Person记录
        Person person = new Person();
        person.setName("person");
        person.setAge(20);

        //一条Student记录
        Student student = new Student();
        student.setName("student");
        student.setAge(22);
        student.setSchool("school");

        //保存
        session.save(person);
        session.save(student);
    }

    //查
    @Test
    public void test2(){
        /**
         * 1. 查询父类记录,需把父表和子表记录汇总到一起再做查询,性能稍差
         * 2. 查询子类记录,做一个内连接查询
         */

        //查询条件中"FROM Person"  - Person不是表名,是类名!
        List<Person> persons = session.createQuery("FROM Person").list();
        System.out.println(persons.size());

        //查询条件中"FROM Student"  - Student不是表名,是类名!
        List<Student> students = session.createQuery("FROM Student").list();
        System.out.println(students.size());
    }


    @Test
    public void test3(){
        /**
         * "UPDATE Person":
         * 1. Person是实体类名,不是数据表名
         * 2. 更新时,只要跟Person有继承关系的子类,都会进行update age字段
         */
        String sql = "UPDATE Person p SET p.age= 20";
        session.createQuery(sql).executeUpdate();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值