Hibernate实战_笔记18(基于注解的元数据)

来源:互联网 发布:js控制input disabled 编辑:程序博客网 时间:2024/05/16 18:30

基于注解的元数据

      基本思想是把元数据与它所描述的信息放在一起,而不是所它分离到一个不同的文件中去。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 {//...}
      这个公共的类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",并在单个搜索结果中得到你应用程序中所有非标准注解的一个全面概览。
      类中的注解仅仅涵盖适用于该特定类的元数据。然而,在更高的级别上经常需要元数据,用于整个包,甚至整个应用程序。在讨论这些方法之前,要介绍另一种映射元数据格式。

4、JPA和EJB3.0中的XML描述符

      EJB3.0和Java Persistence标准都争先包含了注解。然而,专家组已经注意到了XML部署描述符在某些情况下的优势,特别对于随着每次部署而改变的配置元数据。结果,      EJB3.0和JPA中的每一个注解都可以用一个XML描述符元素替换。换句话说,如果你不想用,就不必使用注解(不过强烈推荐使用)。
      来看一下特定持久化单元的JPA XML描述符示例:
      注意:xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"书上这么写的,但是程序总是报错,无意在一个国外的网站上看到了另一种写法。

      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"这是可以的,嘻嘻,运气好,就找到咯,不过XML这方面不是很了解,希望大家分享一下。

<?xml version="1.0" encoding="UTF-8"?><entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"version="1.0"><persistence-unit-metadata><xml-mapping-metadata-complete/><!--为持久化单元禁用注解数据--><persistence-unit-defaults><!--持久化单元默认值--><schema>System</schema><!--设置默认持久化单元模式--><!--<catalog></catalog>注意大多数数据库没有Catalog咯--><access>FIELD/PROPERTY</access> <!--为持久化单元设置默认访问模式--><cascade-persist/><!--配置persistence-by-reachability语义--></persistence-unit-defaults></persistence-unit-metadata><package>cn.jbit.entity</package><entity class="User" name="tbl_user" access="PROPERTY" metadata-complete="true"><attributes><id name="id"><generated-value/></id><basic name="username" optional="false"><column name="uname"/></basic><basic name="password" optional="false"><column name="upwd"/></basic></attributes></entity></entity-mappings>

Catalog Task这个标签我试了好久,原来是Oracle数据库不支持,如表:
供应商Catalog支持Schema支持Oracle不支持Oracle User IDMySQL不支持数据库名MS SQL Server数据库名对象属主名,2005版开始有变DB2指定数据库对象时,Catalog部分省略Catalog属主名SybaseSybase数据库属主名Informix不支持不支持PointBasePointBasePointBase      这个XML由JPA提供程序自动挑选,如果把它放在classpath中持久化单元的META-INF目录下的一个名为orm.xml的文件中的话。你会看到只需要给一个类命名一个标识符属性;就像在注解中一样,实体类的所有其他属性也通过一个明显的默认映射自动地被认为是持久化的。
也可以给整个持久化单元设置默认映射,例如Schema名称和默认的级联选项。如果包括<xml-mapping-metadata-complete>元素,JPA提供程序则完全忽略这个持久化单元中实体类的全部注解,并且仅仅依赖如同在orm.xml文件中定义的映射。
      如果不想忽略而是要覆盖注解元数据,就先从org.xml文件中移除全局的<xml-mapping-metadata-complete>元素。还要从任何应该覆盖(而不是取代)注解的实体映射中移除metadata-complete="true"属性。
      在Java Persistence中使用XML部署描述符的一个明显的问题是,它们与原生的Hibernate XML映射文件的兼容性。这两种格式根本不兼容,你应该决定使用一种或者另一种。JPA XML描述符的语法比原生的Hibernate XML映射文件更接近于实际的JPA注解。
      当决定一种XML元数据格式时,还要考虑供应商扩展。Hibernate XML格式支持所有可能的Hibernate映射,因此如果有些东西无法在JPA/Hibernate注解中被映射,则可以用原生的Hibernate XML文件映射。同样的事情对于JPA XML描述符则不是如此——它们只提供覆盖规范的方便且具体化的元数据。
      另一方面,你无法用Hibernate XML映射文件覆盖注解;必须用XML格式定义一个完整的实体类映射。
      如果正使用JDK5.0,就考虑JPA/Hibernate注解为首选。如果想把一个特定的类映射具体化,或者利用一个不能作为注解使用的Hibernate扩展,就回到原生的Hibernate XML映射文件。如果不打算使用任何供应商扩展(实际上,这是不可能的),或者如果只想覆盖几个注解,或者如果需要甚至包含部署描述符的完整可移植性,就考虑用JPA XML描述符。
      但是如果你习惯使用JDK1.4(或者甚至1.3),却又仍然想要享受行内元数据的更好重构能力和减少代码行的好处时,该怎么办?
下面的内容是介绍XDoclet,感觉知识点好老,都是JDK版本1.4、1.3。。。多学一点,总是有好处的,哈哈。
3 0
原创粉丝点击