您的位置:首页 > 其它

Hibernate继承与多态查询-subclass

2017-01-07 18:55 375 查看
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个实体之间继承,将会很麻烦
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate 继承 多态