千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0

继承映射策略之----每个子类一张表

在每个子类一张表的映射策略中,每一个子类都有一张属于自己的表,但是这张表只包括了定义在这个子类上面的属性而已,定义在它的父类的属性它的表里面是没有的,所以这样的方式映射的话,就不会浪费一点资源了,每一张表,每一列都是不可少的,也不会出现冗余。这种格式是有点像TABLE_PER_CLASS的策略,只不过这种方案是规范的,没有像TABLE_PER_CLASS一样重复定义列,在这里我们叫它JOINED策略。

按我们的例子,这种策略映射出来的话,数据库的结构将如下所示:

 

create table Person (
   id 
integer primary key not null,
   firstName 
varchar(255),
   lastName 
varchar(255),
);

create table Customer (
   id 
integer primary key not null,
   street 
varchar(255),
   city 
varchar(255),
   state 
varchar(255),
   zip 
varchar(255),
);

create table Employee (
   EMP_PK 
integer primary key not null,
   employeeId 
integer
);

 

当持久化管理器加载一个类或者查询一个子类的时候,它必须要对数据库做连接动作,所以我们必须要保存这几张表有一个能够彼此连接起来的列。在我们的例子里面,EMPLOYEE, CUSTOMER, 和 PERSON表共享同样的主键值,这种策略的注释也是挺简单的:

 

@Entity
@Inheritance(strategy
=InheritanceType.JOINED)
public class Person {

}

@Entity
public class Customer extends Person {

}

@Entity
@PrimaryKeyJoinColumn 
(name
="EMP_PK")
public class Employee extends Customer {

}

 

在持久化的时候,持久化管理器需要知道每一张表用哪一列来进行连接,所以当我们要指定某一列的时候,就可以用如下注释:

 @javax.persistence.PrimaryKeyJoinColumn,它的声明如下:
 

 package javax.persistence;

@Target({TYPE, METHOD, FIELD})
public @interface PrimaryKeyJoinColumn
   String name( ) 
default "";
   String referencedColumnName( ) 
default "";
   String columnDefinition( ) 
default "";
}

 

name()方法提出你此表中需要用来连接的列的名字,它默认是与父类的主键进行连接,当我们不想与父类的主键进行连接时,我们可以用referencedColumnName( )这个方法来指定你要连接父类的哪个具体的列,它可以被定义为父类的任意列,但是默认是连接父类的主键列,如果从父类到子类的主键名都是一样的,那么这个属性就没必要再设了,因为Customer和Person的主键是一样的,所以在Customer里面不需要定义任何额外的属性,一切默认就可以了,但是由于Employee里面的主键名和其它的不一样,所以它必须显式地声明它的主键是哪一个。如果有的类有复合主键,那么可以用这个注释:
@javax.persistence.PrimaryKeyJoinColumns

 

package javax.persistence;

@Target({TYPE, METHOD, FIELD})
public @interface PrimaryKeyJoinColumns {
   @PrimaryKeyJoinColumn[] value( );
}

 

它包括了多个@PrimaryKeyJoinColumn的注释。

注意:有些持久化实现这种策略会需要一个辨别器列,虽然大部份是不需要的,所以最好是在使用前查看一下你的持久化提供商的实现说明。

优点:
这种策略虽然没有SINGLE_TABLE策略的速度快,但是你可以定义任何的非空约束在任何的表里面,并且这种模式是规范化的。
缺点:
唯一的缺点就是没有SINGLE_TABLE 策略的性能好。

到现在我们三种处理继承映射的策略都说完了,在不同的场合和环境下选择不同的映射策略是最明智的选择,没有一种策略可以胜任所有场合,否则的话,出一种就可以了,干嘛还出三种呢。希望大家在实际工作中选出适合自己的映射策略,更好的提高工作效率。




尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2007-10-10 00:35 千里冰封 阅读(1125) 评论(0)  编辑  收藏 所属分类: JAVAEE

只有注册用户登录后才能发表评论。


网站导航: