Hibernate继承与多态查询-subclass

public class Person {
    private Integer id;
    private String name;
    private Integer age;

}
public class Worker extends Person{
    private String job;
    private String unit;
}

hibernate为我们提供了三种形式来表示继承关系,分别是:subclass,joined-subclass,union-subclass

1.subclass

父类和子类存在同一张表中,其中的role字段是辨别者列,用于辨别这条记录是父类还是子类

2.join-subclass

不同于subclass,joined-subclass和union-subclass都是需要两种表来存储。
父类表存储父类字段,子类表存储子类字段,虽然没有了辨别者列,但是额外增加了一个person_id来表示二者的关系\

3.union-subclass

这种方式只要和joined-subclass比较一下就很清楚了,join-subclass是父类表存储父类字段,子类表存储子类字段,那么union-subclass就是父类表存储父类字段,而子类表既要存储父类字段,也要存储子类字段

1.subclass

请注意class和subclass的discriminator-value属性,由于父类表和子类表共存在一张表中,因此需要一个辨别者列,我们需要分别对父类和子类设置辨别者列的值,本例中使用PERSON和WORKER。
在中间位置的,它必须在id元素之后,property元素之前,否则会报错,它用于设置辨别者列字段名,column=”role”

<?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 package="cn.sina.subclass">
    <class name="Person" table="ex_person" **discriminator-value="PERSON"**>
        <id name="id" column="pid" length="10" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <!-- 辨别者列 -->
        **<discriminator column="role" type="string"></discriminator>**
        <property name="name" type="java.lang.String" length="32" not-null="true"></property>
        <property name="age" type="java.lang.Integer" length="5" not-null="true"></property>
        **<subclass name="Worker" discriminator-value="WORKER">**
            <property name="job" type="java.lang.String" length="32"></property>
            <property name="unit" type="java.lang.String" length="32"></property>
        </subclass>
    </class>
</hibernate-mapping>
        Person person = new Person();
        person.setAge(10);
        person.setName("tom");
        session.save(person);

        Worker worker = new Worker();
        worker.setAge(20);
        worker.setName("jerry");
        worker.setJob("washer");
        worker.setUnit("bj");
        session.save(worker);

发出的sql如下,除了第一个用于寻找主键最大值外,我们可以看到在插入的是同一张表,同时辨别者列的值已经确定下来了

Hibernate: select max(pid) from ex_person
Hibernate: insert into ex_person (name, age, role, pid) values (?, ?, 'PERSON', ?)
Hibernate: insert into ex_person (name, age, job, unit, role, pid) values (?, ?, ?, ?, 'WORKER', ?)

接下我们看看多态查询,代码如下:
““
//hql查询
List persons = session.createQuery(“from Person”).list();
List workers = session.createQuery(“from Worker”).list();
System.out.println(persons);
System.out.println(workers);

发出的sql以及结果如下:
````
Hibernate: 
select
        person0_.pid as pid0_,
        person0_.name as name0_,
        person0_.age as age0_,
        person0_.job as job0_,
        person0_.unit as unit0_,
        person0_.role as role0_ 
    from
        ex_person person0_
Hibernate: 
select
        person0_.pid as pid0_,
        person0_.name as name0_,
        person0_.age as age0_,
        person0_.job as job0_,
        person0_.unit as unit0_,
        person0_.role as role0_ 
    from
        ex_person person0_
    where
        worker0_.role='WORKER'
[Person [id=1, name=tom, age=10], Worker [job=washer, unit=bj]]
[Worker [job=washer, unit=bj]]

结果在查询父类时,会同时查询出子类,而在查询子类时,使用了where条件,通过辨别者列查询

subclass的缺点:
1.子类独有的字段无法设置not-null约束,即job和unit无法非空,毕竟父类中没有这两个字段
2.如果继承树过于庞大,不便于管理,本例只是两个实体,如果有n个实体之间继承,将会很麻烦

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值