EJB3持久化规范(第九章)

1         O/R映射的元数据
由应用表达的O/R映射的元数据表是应用域对象协议的一部分。
O/R映射元数据是应用域对象协议的一部分。它表达了映射应用域的实体和关系到数据库的需求和期望。和应用域模型一致的基于数据库Schema书写的查询(特殊情况下是SQL查询)依赖于由O/R映射的元数据表达的映射关系。这个规范的实现必须假定应用是依赖于O/R映射元数据,并且确保被这些映射表达的语义和需求是可观察到的。
允许但不要求规范的实现支持生成DDL。可移植的应用不应当依赖于DDL生成。
1.1    O/R映射的注解符
这些注解符在javax.persistence包内。
XML 元数据可以作为注解符的替换方案,或者可以用于重载或参数化注解符,这在第10章描述。
Table注解符指定注解实体的主表。从表可以用SecondaryTable或SecondaryTables来指定。
表4列出了指定Table注解符时会用到的注解符元素,以及这些元素的缺省值。
如果一个实体类没有指定Table注解符,那么将使用表4中定义的缺省值。
例如:
SecondaryTable用于指定实体类的从表。指定一个或多个从表说明实体数据被存在多个表中。
表5列出了可以在SecondaryTable注解符中指定的注解符元素以及这些元素的缺省值。
如果没有指定SecondaryTable,那么就假定实体的所有持久化属性或字段都被映射到主表。如果没有指定主键关联列,那么关联列就假定为主表的主键列,并且和主键列有相同的名字和类型。
例1:只有一个主键列的单一从表
例2:有多个主键列的单一从表
SecondaryTables用于指定多个从表。
例1:假定主键列和所有表的主键名称相同的多个从表。
例2:假定主键列和所有表的主键名称不相同的多个从表。
UniqueConstraint用于指定在为主表或从生成的DDL中的唯一约束。
表6列出了可以在UniqueConstraint中指定的注解符元素。
例子:
Column用于为持久化属性或字段指定映射列。
表7列出了可以在Column注解符内指定的注解符元素以及这些元素的缺省值。
如果没有指定 Column ,那么使用表 7 内的缺省值。
 
例1:
例2:
例3:
JoinColumn用于为连接一个实体关联指定映射列。
表8列出了可以在JoinColumn注解符中指定的注解符元素以及它们的缺省值。
如果没有指定JoinColumn注解符,那么假定连接列是单一的列。连接列的缺省值如下所述。
注解符name元素定义外键列的名称。其余的注解符元素(除了refernecedColumnName)指的是列,和Column注解符的语义一样。
如果有一个单一的连接列,且如果没有指定name元素,那么关联列的名字的格式如下:引用实体的引用关系属性或字段的名字+“_”+被引用的主键列的名字。如果在实体内没有这样的关系属性或字段(如使用关联表),那么关联列的名字的格式是:实体的名字+“_”+被引用的主键列的名字。
如果没有指定refernecedColumnName,外键假定就是被引用表的主键。
如果有多个连接列,那么必须用JonColumns注解符为每一个连接列指定一个JoinColumn。同时也必须为每一个JoinColumn指定元素name和refernecedColumnName。
是否支持被引用列不是被应用表的主键在这个版本中是可选的,但在下一个版本中会要求至此。
例子:
通过JoinColumns注解符可以支持组合键。这可以为同一关系或表关联组合多个JoinColumn。
当使用JoinColumns注解符时,必须为每一个JoinColumn指定元素name和referencedColumnName。
例子:
1.1.3    Id注解符
Id注解符指定实体的主键属性或字段。Id注解符可以用于实体或映射的超类上。
缺省情况下,属性的映射列的格式假定为主表的主键。如果没有指定Column注解符,那么主键列的名字假定和唯一标识属性或字段的名字是相同的。
例子:
1.1.4    注解符GeneratedValue
GeneratedValue注解符提供主键的生成策略规范。GeneratedValue可以应用到实体的主键属性或字段,也可以应用到和Id注解符关联的被映射的超类上。(可移植的应用不应当在其他的字段上使用GeneratedValue)
表9列出了可以在GeneratedValue中指定的注解符元素以及它们的缺省值。
主键生成的类型在GenerationType枚举中定义:
l TABLE策略指的是持久化提供商应当使用后台数据库表来指派唯一标识。
l SEQUENCE和IDENTITY策略分别指的是使用数据库序列或唯一标识列。
l AUTO策略指的是持久化提供商根据特定的数据库来确定一个合适的策略。AUTO策略可以认为数据库资源存在,或者企图去创建它。提供商可以提供在不支持Schema生成或在运行时不能创建Schema资源的情况下如何去创建这样资源的文档。
l NONE策略指的是不使用持久化提供商的主键生成,应用负责分派主键。
本规范没有定义这些策略的确切行为。
 
例1:
例2:
AttributeOverride用于重载基本的(不管是显式的还是缺省的)属性/字段或Id属性/字段的映射。
AttributeOverride可以用于一个继承超类的实体或一个被嵌入的字段/属性来重载定义在父类或可嵌入类的基本映射信息。如果没有指定AttributeOverride,被映射的列名和原始映射的列名相同。
表10列出了可以在AttributeOverride注解符中指定的注解符元素。
column元素指的是包含了这个注解符的类对应的数据库表中的列名。
例子:
AttributeOverrides用于重载多个属性或字段的映射。
例子:
1.1.3    注解符AssociationOverride
AssociationOverride用于重载表示实体关系的属性或字段的多对一或一对一映射。
AssociationOverride可以用于一个继承超类的实体,在这个超类内定义了多对一或一对多的映射。如果没有指定AssociationOverride,那么关联列被映射的名字和原始映射相同。
表11列出了可以在AssociationOverride中指定的注解符元素。
元素joinColumns指的是包含这个注解符的类对应的数据库表中的列名。
例子:
1.1.4    注解符AssociationOverrides
用于重载多个多对一或一对一关系属性或字段的映射。
例子:
EmbeddedId用于表示一个实体类或超类的一个持久化属性或字段是组合主键,这个主键是一个可嵌入类。可嵌入类必须注解为Embeddable。(注意,Id注解符不使用在可嵌入类中)
当使用EmbeddedId时,只能有一个EmbeddedId,且不能有Id注解符。
例子:
IdClass用于为实体类或超类指定一个组合主键类,这个类映射到实体的多个属性或字段。
在主键类中的主键字段或属性的名字和实体类中的主键字段或属性必须一一对应,并且他们的类型也必须是一致的。参考1.1.4章节,“主键和实体唯一标识”。
Id注解符也必须应用到这些对应的字段或属性上。
例子:
Transient用于指定实体类、超类或可嵌入类的属性或字段不是持久化的。
例子:
Version指定实体类的版本属性作为乐观锁的值。这用于执行merge操作时确保完成性和乐观的并发控制。
每个类只有一个Version属性/字段;使用多个Version属性/字段的应用可能是不可移植的。
Version属性应当被映射到实体类的主表上,映射到其他表上的应用是不可移植的。
通常情况下,被Version注解符指定的字段或属性不应当被应用更新。(特殊情况,参考3.10)
Version属性可以是以下类型:int,Integer,short,Short,long,Long,Timestamp。
例子:
Basic是映射到数据库列的最简单的类型。它可以应用到下列类型的任何持久化属性或实例变量上:java原始类型及其包装类型,java.lang.String,java.math.BigInteger,java.math.BigDecimal,java.util.Date,java.util.Calendar,java.sql.Date,java.slq.Time,java.sql.Timestamp,byte[],Byte[],char[],Character[],枚举,和任何实现了序列化接口的类型。和1.1.6章节描述的一样,对这些类型的持久化字段或属性使用Basic注解符是可选的。
表12列出了可以在Basic注解符内指定的注解符元素以及它们的缺省值。
FetchType枚举定义了从数据库获取数据的策略:
l EAGER策略是持久化提供商运行时应当提供的饥渴提取数据策略。
l LAZY策略是持久化提供商运行时的缺省提供的提取数据策略。
实现可以在缺省为LAZY提取策略时改变为饥渴提取数据。对Basic属性,懒惰提取只可以被应用到那些总是通过基于属性获取方法的属性上。
Optional元素能被用作指定字段或属性的值是否可以为null。这不考虑原始类型,原始类型被认为是必须有值的。
例1:
例2:
1.1.10   Lob注解符
Lob用于指定持久化字段或属性是个大对象类型。当映射到数据库的Lob类型时,可移植的应用应当使用Lob注解符。Lob注解符可以和Basic注解符联合使用。Lob类型可以是二进制类型,也可以是字符类型。Lob类型从持久化字段或属性的类型推断出来,且除了字符串和基于字符的类型外,缺省值都是Blob。
例1:
例2:
1.1.11   注解符Temproal
Temproal注解符必须用于指定java.util.Date和java.util.Calendar类型的持久化字段或属性。它只能用于指定这些类型的字段或属性。
Temproal可以和Basic联合使用。
TemproalType枚举定义这些临时类型的映射。
表13列出了可以在Temporal注解符内指定的注解符元素以及它们的缺省值。
例子:
1.1.12   注解符Enumerated
Enumerated指定一个持久化字段应当作为枚举类型存储。Enumerated可以和Basic注解符联合使用。
枚举可以被映射成字符串或整数。EnumType定义了枚举类型映射。
如果没有指定枚举类型或没有使用Enumerated,那么枚举类型假定是ORDINAL。
表14列出了可以在Enumerated注解符中指定的注解符元素以及他们的缺省值。
例子:
如果status属性被映射成整型列,并且payscale属性被映射成varchar类型的列,那么一个有PART_TIME的status和JUNIOR的pay rate将分别被存储为STATUS=1和PAYSCALE=”JUNIOR”。
ManyToOne定义一个到有多对一关联的实体类的单值关系。由于可以从被引用的对象类型推断出目标实体,所以,通常情况下,不需要显式指定目标实体。
表15列出了ManyToOne注解符内可以指定的注解符元素以及它们的缺省值。
Cascade元素指定会繁衍到关联实体的级联操作集合。级联操作的类型由CascadeType枚举定义:
Cascade=ALL等价于cascade={PERSIST,MERGE,REMOVE,REFRESH}。
当使用EAGER策略时,持久化提供商运行时应当是即时获取关联实体。LAZY策略是缺省的策略。实现必须允许能将缺省策略改为EAGER策略。
 
例子:
OneToOne定义了到另一个实体的单值关联,这个实体有一对一多样性。由于可以从被引用的对象类型推断出目标实体,所以,通常情况下,不需要显式指定目标实体。
表16列出了可以在OneToOne注解符内指定的注解符元素。
例1:使用外键列的一对一关联
在Customer类上:
在CustomerRecord类上:
例2:假定源和目标共享同一个主键值的一对一关联。
在Employee类上:
在EmployeeInfo类上:
OneToMany定义多值关联。
如果用泛型指定了集合内的元素类型,那么不需要指定关联目标实体类型,否则必须指定目标实体类。
表17列出了可以在OneToMany注解符中指定的注解符元素以及它们的缺省值。
单向的一对多关系的缺省schema 层的映射使用一个关联表,在1.1.8.5 章节中描述。单向一对多关系也可以用一对多外键映射来实现,然而,在这个版本中不要求支持。对一对多关系想使用外键映射策略的应用应当使用双向关系确保可移植性。
例1:用泛型的一对多关系
在Customer类上:
在Order类型上:
例2:不使用泛型的一对多关系
在Customer类中:
在Order类中:
JoinTable用于关系的映射。在多对多关系的拥有者端指定,或者在单向一对多关系指定。
表18列出可以在JoinTable注解符中指定的注解符元素以及它们的缺省值。
如果没有指定JoinTable,则使用注解符元素的缺省值。
关联表的名字假定是:用下划线连接被关联主表的表名,拥有者的表名放在首位。
 
例子:
ManyToMany定义多对多关系的多值关联。如果用泛型指定了集合内的元素类型,那么不需要指定关联目标实体类型,否则必须指定目标实体类。
每一个多对多关联有两端,拥有者端和非拥有者或反向端。在拥有者端指定关联表。如果关联是双向的,另一个端也可以被指派为拥有者端。
OneToMany注解符的注解符元素同样可以应用到ManyToMany注解符。
表17列出了这些注解符元素以及它们的缺省值。
例1:
在Customer类中:
在PhoneNumber类中:
例2:
在Customer类中:
在PhoneNumber类中:
例3:
在Customer类:
在PhoneNumber类中:
MapKey用于指定java.util.Map类型关联的map主键。
元素name指派关联实体的持久化字段或属性的名称,这个关联实体用于做map主键。如果没有指定name,将使用主键作为map主键。如果主键是组合主键,且映射为IdClass,那么主键类的实例用作map主键。
如果一个不是主键的持久化字段或属性被用作map主键,那么它应当有一个唯一约束。
例1:
例2:
OrderBy用于指定在获取关联时确定关联值集合元素的顺序。
排序元素的语法是一个orderby_list,如下所示:
如果没有指定ASC还是DESC,那么缺省是ASC。
如果没有指定排序元素,那么缺省是按主键排序。
排序的属性或字段名必须和关联类的字段或属性名一一对应。在排序中使用的属性或字段必须和比较操作中支持的列一一对应。
例子:
Inheritance定义实体类层次的继承策略。它在类层次的根上指定。
本规范不要求支持继承策略的组合。可移植的应用在实体层次中应当只使用一个单一继承策略。
三种继承策略是:
l 每个类层次是一个表。
l 每个类是一个表。
l 关联子类策略。
参考2.1.10章节了解更详细的继承策略。继承策略选项在InheritanceType枚举中定义:
在这个版本中是否支持TABLE_PER_CLASS策略是可选的。
如果没有指定Inheritance或没有指定继承类型,则使用SINGLE_TABLE策略。
19 列出了可以在 Inheritance 注解符中指定的注解符元素以及它们的缺省值。
 
例子:
1.1.1    注解符DiscrminatorColumn
对SINGLE_TABLE策略,典型地也是对JOINED策略,持久化提供商将使用一个类型区分列。DiscrminatorColumn用于为SINGLE_TABLE和JOINED继承映射策略定义区分列。
继承映射策略和区分列只在类层次的根上指定,或者在子层次上使用不同的映射策略。
DiscrminatorColumn可以被指定在实体类上(包括抽象实体类)。
如果没有指定DiscrminatorColumn,并且还要求区分列,那么区分列的名称缺省为“DTYPE”,且区分列的类型为STRING。
表20列出了可以在DiscrminatorColumn注解符中指定的注解符元素以及他们的缺省值。
支持的区分类型在DiscriminatorType枚举中定义:
如果在可选的columnDefinition元素中指定值,那么区分列的类型和区分器类型一致。
例子:
1.1.2    注解符DiscriminatorValue
DiscriminatorValue用于指定区分列的值。DiscriminatorValue只能用在具体的实体类上。如果没有指定DiscriminatorValue,而且还使用了区分列,那么提供商特定的功能会用于生成一个代表这个实体类型的值。
继承策略和区分列只是在实体类层次根上或使用不同继承策略的子层次上指定。区分列的值如果没有缺省值,则应当为类层次上的每一个实体类指定。
表21列出了可以在DiscriminatorValue注解符内指定的注解符元素以及它们的缺省值。
区分列的值必须和被指定列(或缺省的区分列)的类型一致。如果区分列的类型是整型,那么它被指定的值必须可以被转化为整型值(如,“1”)。
例子:
PrimarykeyJoinColumn指定用作外键(关联到另外一个表)的主键列。
在JOINED策略中,PrimarykeyJoinColumn用于将实体子类的主表关联到父类的主表。它在SecondaryTable注解符中被用于将从表关联到主表;它可以被用在OneToOne映射中,在这个映射中引用实体的主键用作被引用实体的外键。
表22列出了可以在PrimarykeyJoinColumn注解符中指定的注解符元素以及它们的缺省值。
如果在JOINED映射策略中没有为子类指定PrimarykeyJoinColumn注解符,那么假定外键列的名字和父类主表的主键列相同。
例子:Customer和valuedCustomer子类
通过PrimaryKeyJoinColumns可以支持组合主键。PrimaryKeyJoinColumns组合了PrimaryKeyJoinColumn。
例子:ValuedCustomer子类
例子:在Employee和EmployeeInfo类之间的OneToOne关系
Embeddable用于标记一个对象是作为一个实体内在的部分被存储,这个对象和实体共享唯一标识。嵌入对象的每个持久化属性或字段都被映射到数据库表。只有Basic,Column、Lob、Temporal和Enumerated映射注解符可以方便地用于映射注解为Embeddable的类的持久化字段或属性。(Transient可以用于指派可嵌入类的非持久化状态)
例子:
Embeded用于指定值为可嵌入类的实例的实体的持久化字段或属性。
AttributeOverride和/或AttributeOverrides注解符可以用于重载声明在可嵌入类的列的映射,这个可嵌入类被映射成实体表。
不要求实现支持被嵌入对象被映射成多个表(例如,分成主表和从表或多个从表)。
例子:
MappedSuperClass指派一个类,这个类的映射信息应用到它的子类上。被映射的超类没有单独的表。
由于被映射的超类没有数据库表,所以除了映射只应用到它的子类上外,用MappedSuperClass注解符指派的类可以用同样的方式被映射作为实体。当应用到子类时,继承的映射将应用在子类表的上下文中。在这样的子类中,可以用AttributeOverride来重载映射信息。
当指定GeneratedValue注解符的生成器元素时,SequenceGenerator定义一个可以通过名字引用的主键生成器。生成器可以定义在类、或字段/属性上。序列生成器可以指定在实体类或注解字段/属性上。生成器名字的范围在持久化单元内是全局的(跨所有的生成器类型)。
表23列出了可以在SequenceGenerator注解符中指定的注解符元素以及它们的缺省值。
例子:
当指定GeneratedValue注解符的生成器元素时,TableGenerator定义一个可以通过名字引用的主键生成器。生成器可以定义在类、或字段/属性上。序列生成器可以指定在实体类或注解字段/属性上。生成器名字的范围在持久化单元内是全局的(跨所有的生成器类型)。
表24列出了可以在TableGenerator注解符内指定的注解符元素以及它们的缺省值。
元素table指定了用于持久化提供商存储生成的id值的表的表名。实体类型典型地用它自己表中的行来生成id值。Id值通常是正整数。
例1:
例2:
1.2    O/R映射注解符使用样例
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值