基于注解的元数据
基本思想是把元数据与它所描述的信息放在一起,而不是所它分离到一个不同的文件中去。Java在JDK5.0之前并不具备这项功能,因此开发了一种可供选择的方案。XDoclet项目使用支持键/值对的特殊Javadoc标签,引入了包含元信息的Java源代码的注解。通过标签的嵌套,非常复杂的结构也得到了支持,但是只有一些IDE允许为自动突破性呈验证定制Javadoc模板。
Java规范请求(JSR)175在Java语言中引入了注解概念,给注解的定义使用类型安全和声明的接口。自动完成和编译时检查不再是问题。
现在我们要介绍映射注解并使用JDK5.0.如果你必须使用JDK1.4,但是又喜欢使用基于注解的元数据,那就考虑我们后面讨论的XDoclet.
1、定义和使用注解
import javax.persistence.*;
@Entity
@Table(name="TBL_ITEM")
public class Item {
//…
}
本文由java培训机构分享这个公共的类Item,已经被声明为持久化实体。它的所有属性现在都用默认策略自动持久化。还显示了另一个注解,它声明这个持久化类被映射到的那个数据库Schema中的表名。如果省略这个信息,JPA提供程序默认为未限定类名(unqualified class name),就像如果你在一个XML映射文件中省略表名时Hibernate所做的处理那样。
所有这些都是类型安全的,因此当Hibernate启动时,被声明的注解通过Java Reflection读取。你不需要编写任何XML映射文件,Hibernate无需解析任何XML,并且启动更快。 IDE也可以轻松地验证和强调注解--毕竟它们是普通的Java类型。
注解明显的好处之一是它们对于敏捷开发的灵活性,如果你经常重构代码、重新命名、删除或者移动类和属性的话。大部分开发工具和编辑器都无法重构XML元素和属性值,但是注解是Java语言的一部分,包括在所有重构操作中。
应该应用哪些注解呢?有几个标准的且特定于供应商的包可供你选择。
2、考虑标准
基于注解的元数据对于你如何编写Java应用程序有着重大的影响。其他编程环境,比如C#和。NET,早就具备这种支持,开发人员很快就采用了元数据属性。在Java世界里,注解的广泛应用是在JavaEE 5.0中。所有被认为是JavaEE一部分的规范,如EJB、JMS(Java Message Service)、JMX甚至servlet规范,都将被更新,并因为元数据需要而使用JDK5.0注解。Sun公司引进了一项规范成果(JSR250)来处理不同规范的注解,给整个Java平台定义一般的注解。然而,对你于在持久层上的工作,最重要的规范则是EJB3.0和JPA.
一旦你已经在classpath中包括了JAP接口,来自Java Persistence包的注解在javax.persistence中就可以使用了。可以用这些注解声明持久化的实体类、可嵌入的类、属性、字段、键等。JPA规范覆盖了基础的和最相关的高级映射--编写一个可移植的应用程序所需要的一切,包含一个可插拔的、标准的持久化层,在任何运行时容器的内部和外部都适用。
Java Persistence中没有指定哪些注解和映射特性?特定的JPA引擎和产品一般可以提供这些优势--所谓的供应商扩展。
3、利用供应商扩展
即使你用javax.persistence包中JPA兼容的注解映射了应用程序的大部分模型,有时候还是必须使用供应商扩展。例如,你希望在高质量的持久化软件中可用的几乎所有的 性能调优选项,例如抓取和高速缓存设置,都只作为特定于Hibernate的注解。
我们在一个例子中看看这会是什么样。再次注解Item实体源代码:
import javax.persistence.*;
@Entity
@Table(name="TBL_ITEM")
public class Item {
//…
}
这个例子包含了两个Hibernate注解。第一个注解@BatchSize是一个抓取选项,可以在本书稍后要验证的几种情况下提升性能。第二个注解@DiscriminatorFormula是一个 Hibernate映射注解,当类继承无法用简单的文字值(literal value)决定的时候(此处它映射了一个遗留的列ITEM_IS_SPECIAL--或许某种标记--到一个文字值),对于遗留的模式特别有用。这两个注解都用org.hibernate.annotations作为包名的前缀。把这当作一个好的实战,因为你现在可以很容易地看到这个实体的什么元数据是来自JPA规范,以及哪些标签是特定于供应商的。你还可以轻松地搜索源代码里的"org.hibernate.annotations",并在单个搜索结果中得到你应用程序中所有非标准注解的一个全面概览。
类中的注解仅仅涵盖适用于该特定类的元数据。然而,在更高的级别上经常需要元数据,用于整个包,甚至整个应用程序。在讨论这些方法之前,要介绍另一种映射元数据格式。