Hibernate实战_笔记18(基于注解的元数据)
2014-03-12 22:23
232 查看
基于注解的元数据
基本思想是把元数据与它所描述的信息放在一起,而不是所它分离到一个不同的文件中去。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 ID |
MySQL | 不支持 | 数据库名 |
MS SQL Server | 数据库名 | 对象属主名,2005版开始有变 |
DB2 | 指定数据库对象时,Catalog部分省略 | Catalog属主名 |
Sybase | Sybase | 数据库属主名 |
Informix | 不支持 | 不支持 |
PointBase | PointBase | PointBase |
也可以给整个持久化单元设置默认映射,例如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。。。多学一点,总是有好处的,哈哈。
相关文章推荐
- Hibernate实战_笔记20(全局XML映射元数据、全局的注解元数据、占位符)
- 18.笔记JAVASpring框架学习————基于注解配置Bean之二
- 基于注解的Hibernate配置(笔记)
- Hibernate基于注解的元数据
- Hibernate学习笔记 3 - 关系映射配置(基于注解)
- Hibernate4实战之Hibernate4注解零配置 浏览(88173)|评论(0) 交流分类:Java|笔记分类: 未分类 @Entity,注册在类头上,将一个类声明为一个实体bean
- Hibernate中,One2Many的基于注解Annotation的实现
- Spring4 学习系列之——整合基于注解的Hibernate实例
- hibernate validator自定义校验注解以及基于服务(服务组)的校验
- hibernate基于注解的维护权反转:@OneToMany(mappedBy=)
- Spring3.0MVC和Hibernate基于annotation注解的整合
- 基于《Selenium 2自动化测试实战》的学习笔记(6)—— CSS 定位
- hibernate 10 事务和并发 | hibernate 实战(第二版) 第10章事务和并发 | 笔记
- Hibernate 映射关系(基于注解)
- Hibernate实战_笔记22(表示XML中的数据)
- 基于注解的maven+spring+hibernate+mysql简单demo
- hibernate 9 使用对象 | hibernate 实战(第二版) 第9章使用对象 | 笔记
- Hibernate实战_笔记23(映射持久化)
- 基于注解的Hibernate配置
- Spring学习笔记(12.基于java的容器注解)