java

位置:IT落伍者 >> java >> 浏览文章

Hibernate的继承关系


发布日期:2023年09月18日
 
Hibernate的继承关系

每个子类对应一个数据表(Table per concrete class)

学生表

create table `sample``student`(

`id` bigint not null auto_increment

`name` varchar() default not null

`score` float

primary key (`id`)

);

create unique index `PRIMARY` on `sample``student`(`id`);

教师表

create table `sample``teacher`(

`id` bigint not null auto_increment

`name` varchar() default not null

`salary` float()

primary key (`id`)

);

create unique index `PRIMARY` on `sample``teacher`(`id`);

Person抽象基类

public abstract class Person implements javaioSerializable {

private Long id;

private String name;

/**defaultconstructor*/

public Person() {

}

public Long getId() {

returnthisid;

}

publicvoid setId(Long id) {

thisid = id;

}

public String getName() {

returnthisname;

}

publicvoid setName(String name) {

thisname = name;

}

}

子类分别实现它并添加额外的属性和相应gettter和setter方法

如Student类

public class Student extends Person {

private Float score;

public Student() {

super();

}

public Float getScore() {

returnscore;

}

publicvoid setScore(Float score) {

thisscore = score;

}

}

hibernatecfgxml

<?xml version= encoding=UTF?>

<!DOCTYPE hibernateconfiguration PUBLIC

//Hibernate/Hibernate Configuration DTD //EN

configurationdtd>

<hibernateconfiguration>

<sessionfactory>

<property name=connectionusername>root</property>

<property name=connectionurl>

jdbc:mysql://localhost:/sample

</property>

<property name=dialect>

orghibernatedialectMySQLDialect

</property>

<property name=connectionpassword></property>

<property name=connectiondriver_class>

commysqljdbcDriver

</property>

<property name=show_sql>true</property>

<property name=current_session_context_class>thread</property>

<mapping resource=powerwind/bean/Studenthbmxml />

<mapping resource=powerwind/bean/Teacherhbmxml />

</sessionfactory>

</hibernateconfiguration>

由于Person抽象类没有对应数据库的表也没有对应的映射文件在HQL查询中也就不支持多态查询感觉上Person抽象类的作用只是减少JAVA代码的编写而已

每个类对应一个表(Table per subclass)

人员表

create table `sample``person`(

`id` bigint not null auto_increment

`name` varchar()

primary key (`id`)

);

学生表

create table `sample``student`(

`id` bigint default not null

`score` float

primarykey (`id`)

);

教师表

create table `sample``teacher`(

`id` bigint default not null

`salary` float

primary key (`id`)

);

两个子类的实现和前一种完全一样 Person类也只是去掉abstract修饰符而已映射文件只需要Personhbmxml一个即可

<hibernatemapping>

<class name=powerwindbeanPerson table=person

catalog=sample>

<id name=id type=javalangLong>

<column name=id />

<generator class=native></generator>

</id>

<property name=name type=javalangString>

<column name=name length= notnull=true />

</property>

<joinedsubclass name=powerwindbeanStudent

table=student>

<key column=id />

<property name=score type=javalangFloat>

<column name=score precision= scale= />

</property>

</joinedsubclass>

<joinedsubclass name=powerwindbeanTeacher

table=teacher>

<key column=id />

<property name=salary type=javalangFloat>

<column name=salary precision= scale= />

</property>

</joinedsubclass>

</class>

</hibernatemapping>

这种方式是支持多态查询的

多态查询语句Query query=sdaogetSession()createQuery(from Person);

一个表对多个类(Table per class hierarchy)

人员表

create table `sample``person`(

`id` bigint not null auto_increment

`name` varchar()

`score` float

`salary` float

`type` char()

primary key (`id`)

);

Personhbmxml

<hibernatemapping>

<class name=powerwindbeanPerson table=person

catalog=sample>

<id name=id type=javalangLong>

<column name=id />

<generator class=native></generator>

</id>

<discriminator column=type type=javalangString />

<property name=name type=javalangString>

<column name=name length= notnull=true />

</property>

<subclass name=powerwindbeanStudent

discriminatorvalue=S>

<property name=score type=javalangFloat />

</subclass>

<subclass name=powerwindbeanTeacher

discriminatorvalue=T>

<property name=salary type=javalangFloat />

</subclass>

</class>

</hibernatemapping>

优点是单表查询支持多态缺点是要在表增加字段(type)用于区分子类

附加实体粒度设计

面向设计的细粒度

人员表

create table `sample``person`(

`id` bigint not null auto_increment

`name` varchar()

`email` varchar()

`phone` varchar()

primary key (`id`)

);

Person类

publicclass Person implements javaioSerializable {

private Long id;

private String name;

private Contact contact;

}

Contact类

publicclass Contact implements javaioSerializable {

private String email;

private String phone;

}

以上两个类的代码省略了getter和setter方法

Personhbmxml

<hibernatemapping>

<class name=powerwindbeanPerson table=person

catalog=sample>

<id name=id type=javalangLong>

<column name=id />

<generator class=native></generator>

</id>

<property name=name type=string column=name/>

<component name=contact class=powerwindbeanContact>

<property name=email type=string column=email/>

<property name=phone type=string column=phone/>

</component>

</class>

</hibernatemapping>

这样的细粒度有什么用呢?应该在处理比较复杂表结构才体现出来吧

面向性能的细粒度

假如Contact类包含的字段是重量级的数据如图片之类而我们一般可能只需要一些简单的信息摘要要怎么做呢?

create table `sample``person`(

`id` bigint not null auto_increment

`name` varchar()

`gender` varchar()

`email` varchar()

`phone` varchar()

primary key (`id`)

);

首先定义个基类BasePerson

publicclass BasePerson {

private Long id;

private String name;

}

Person类继承BasePerson类添加多一个gender属性

PersonDetail类继承Person类添加多一个email和phone属性

Personhbmxml

<class name=powerwindbeanPerson table=person

catalog=sample>

<id name=id type=javalangLong>

<column name=id />

<generator class=native></generator>

</id>

<property name=name type=string column=name/>

<property name=gender type=string column=gender/>

</class>

PersonDetailhbmxml

<class name=powerwindbeanPersonDetail table=person

catalog=sample polymorphism=explicit>

<id name=id type=javalangLong>

<column name=id />

<generator class=native></generator>

</id>

<property name=name type=string column=name />

<property name=gender type=string column=gender />

<property name=phone type=string column=phone />

<property name=email type=string column=email />

</class>

除了polymorphism=explicit这一句和每个子类对应一个数据表的继承关系没有什么区别正是这句设置去除了对PersonDetail的隐式多态查询

Query query=getSession()createQuery(from Person);

Query query=getSession()createQuery(from PersonDetail);

上面两句中第一句并不会查询到PersonDetail 对象即查询字段不包括email和phone

参考《深入浅出hibernate》一书

上一篇:JBPM 整合 Drools(JBoss Rule)

下一篇:Spring Reference