﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-tangbao-文章分类-hibernate</title><link>http://www.blogjava.net/tangbao/category/7439.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 01:48:17 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 01:48:17 GMT</pubDate><ttl>60</ttl><item><title>[转贴]如何从Hibernate2.1升级到Hibernate3.0？ </title><link>http://www.blogjava.net/tangbao/articles/32127.html</link><dc:creator>糖包</dc:creator><author>糖包</author><pubDate>Thu, 23 Feb 2006 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/tangbao/articles/32127.html</guid><wfw:comment>http://www.blogjava.net/tangbao/comments/32127.html</wfw:comment><comments>http://www.blogjava.net/tangbao/articles/32127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/tangbao/comments/commentRss/32127.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/tangbao/services/trackbacks/32127.html</trackback:ping><description><![CDATA[<BR>1.1 Hibernate API 变化 <BR>1.1.1 包名 <BR>1.1.2 org.hibernate.classic包 <BR>1.1.3 Hibernate所依赖的第三方软件包 <BR>1.1.4 异常模型 <BR>1.1.5 Session接口 <BR>1.1.6 createSQLQuery() <BR>1.1.7 Lifecycle 和 Validatable 接口 <BR>1.1.8 Interceptor接口 <BR>1.1.9 UserType和CompositeUserType接口 <BR>1.1.10 FetchMode类 <BR>1.1.11 PersistentEnum类 <BR>1.1.12 对Blob 和Clob的支持 <BR>1.1.13 Hibernate中供扩展的API的变化 <BR>1.2 元数据的变化 <BR>1.2.1 检索策略 <BR>1.2.2 对象标识符的映射 <BR>1.2.3 集合映射 <BR>1.2.4 DTD <BR>1.3 查询语句的变化 <BR>1.3.1 indices()和elements()函数 <BR><BR>尽管Hibernate 3.0 与Hibernate2.1的源代码是不兼容的，但是当Hibernate开发小组在设计Hibernate3.0时，为简化升级Hibernate版本作了周到的考虑。对于现有的基于Hibernate2.1的Java项目，可以很方便的把它升级到Hibernate3.0。 <BR><BR>本文描述了Hibernate3.0版本的新变化，Hibernate3.0版本的变化包括三个方面： <BR>（1）API的变化，它将影响到Java程序代码。 <BR>（2）元数据，它将影响到对象-关系映射文件。 <BR>（3）HQL查询语句。 <BR><BR>值得注意的是， Hibernate3.0并不会完全取代Hibernate2.1。在同一个应用程序中，允许Hibernate3.0和Hibernate2.1并存。 <BR><BR>1.1 Hibernate API 变化 <BR><BR>1.1.1 包名 <BR><BR>Hibernate3.0的包的根路径为: “org.hibernate” ，而在Hibernate2.1中为“net.sf.hibernate”。这一命名变化使得Hibernate2.1和Hibernate3.0能够同时在同一个应用程序中运行。 <BR><BR>如果希望把已有的应用升级到Hibernate3.0，那么升级的第一步是把Java源程序中的所有“net.sf.hibernate”替换为“org.hibernate”。 <BR><BR>Hibernate2.1中的“net.sf.hibernate.expression”包被改名为“org.hibernate.criterion”。假如应用程序使用了Criteria API，那么在升级的过程中，必须把Java源程序中的所有“net.sf.hibernate.expression”替换为“org.hibernate.criterion”。 <BR><BR>如果应用使用了除Hibernate以外的其他外部软件，而这个外部软件又引用了Hibernate的接口，那么在升级时必须十分小心。例如EHCache拥有自己的CacheProvider： net.sf.ehcache.hibernate.Provider，在这个类中引用了Hibernate2.1中的接口，在升级应用时，可以采用以下办法之一来升级EHCache: <BR><BR>（1）手工修改net.sf.ehcache.hibernate.Provider类，使它引用Hibernate3.0中的接口。 <BR>（2）等到EHCache软件本身升级为使用Hibernate3.0后，使用新的EHCache软件。 <BR>（3）使用Hibernate3.0中内置的CacheProvider：org.hibernate.cache.EhCacheProvider。 <BR><BR>1.1.2 org.hibernate.classic包 <BR><BR>Hibernate3.0把一些被废弃的接口都转移到org.hibernate.classic中。 <BR><BR>1.1.3 Hibernate所依赖的第三方软件包 <BR><BR>在Hibernate3.0的软件包的lib目录下的README.txt文件中，描述了Hibernate3.0所依赖的第三方软件包的变化。 <BR><BR>1.1.4 异常模型 <BR><BR>在Hibernate3.0中，HibernateException异常以及它的所有子类都继承了java.lang.RuntimeException。因此在编译时，编译器不会再检查HibernateException。 <BR><BR>1.1.5 Session接口 <BR><BR>在Hibernate3.0中，原来Hibernate2.1的Session接口中的有些基本方法也被废弃，但为了简化升级，这些方法依然是可用的，可以通过org.hibernate.classic.Session子接口来访问它们，例如： <BR>org.hibernate.classic.Session session=sessionFactory.openSession(); <BR>session.delete("delete from Customer "); <BR>在Hibernate3.0中，org.hibernate.classic.Session接口继承了org.hibernate.Session接口，在org.hibernate.classic.Session接口中包含了一系列被废弃的方法，如find()、interate()等。SessionFactory接口的openSession()方法返回org.hibernate.classic.Session类型的实例。如果希望在程序中完全使用Hibernate3.0，可以采用以下方式创建Session实例： <BR><BR>org.hibernate.Session session=sessionFactory.openSession(); <BR><BR>如果是对已有的程序进行简单的升级，并且希望仍然调用Hibernate2.1中Session的一些接口，可以采用以下方式创建Session实例： <BR><BR>org.hibernate.classic.Session session=sessionFactory.openSession(); <BR><BR>在Hibernate3.0中，Session接口中被废弃的方法包括： <BR>* 执行查询的方法：find()、iterate()、filter()和delete(String hqlSelectQuery) <BR>* saveOrUpdateCopy() <BR><BR>Hibernate3.0一律采用createQuery()方法来执行所有的查询语句，采用DELETE 查询语句来执行批量删除，采用merge()方法来替代 saveOrUpdateCopy()方法。 <BR><BR>提示：在Hibernate2.1中，Session的delete()方法有几种重载形式，其中参数为HQL查询语句的delete()方法在Hibernate3.0中被废弃，而参数为Ojbect类型的的delete()方法依然被支持。delete(Object o)方法用于删除参数指定的对象，该方法支持级联删除。 <BR>Hibernate2.1没有对批量更新和批量删除提供很好的支持，参见&lt;&lt;精通Hibernate&gt;&gt;一书的第13章的13.1.1节（批量更新和批量删除），而Hibernate3.0对批量更新和批量删除提供了支持，能够直接执行批量更新或批量删除语句，无需把被更新或删除的对象先加载到内存中。以下是通过Hibernate3.0执行批量更新的程序代码： <BR>Session session = sessionFactory.openSession(); <BR>Transaction tx = session.beginTransaction(); <BR>String hqlUpdate = "update Customer set name = :newName where name = :oldName"; <BR>int updatedEntities = s.createQuery( hqlUpdate ) <BR>.setString( "newName", newName ) <BR>.setString( "oldName", oldName ) <BR>.executeUpdate(); <BR>tx.commit(); <BR>session.close(); <BR>以下是通过Hibernate3.0执行批量删除的程序代码： <BR>Session session = sessionFactory.openSession(); <BR>Transaction tx = session.beginTransaction(); <BR>String hqlDelete = "delete Customer where name = :oldName"; <BR>int deletedEntities = s.createQuery( hqlDelete ) <BR>.setString( "oldName", oldName ) <BR>.executeUpdate(); <BR>tx.commit(); <BR>session.close(); <BR><BR>1.1.6 createSQLQuery() <BR><BR>在Hibernate3.0中，Session接口的createSQLQuery()方法被废弃，被移到org.hibernate.classic.Session接口中。Hibernate3.0采用新的SQLQuery接口来完成相同的功能。 <BR><BR>1.1.7 Lifecycle 和 Validatable 接口 <BR><BR>Lifecycle和Validatable 接口被废弃，并且被移到org.hibernate.classic包中。 <BR><BR>1.1.8 Interceptor接口 <BR><BR>在Interceptor 接口中加入了两个新的方法。 用户创建的Interceptor实现类在升级的过程中，需要为这两个新方法提供方法体为空的实现。此外，instantiate()方法的参数作了修改，isUnsaved()方法被改名为isTransient()。 <BR><BR>1.1.9 UserType和CompositeUserType接口 <BR><BR>在UserType和CompositeUserType接口中都加入了一些新的方法，这两个接口被移到org.hibernate.usertype包中，用户定义的UserType和CompositeUserType实现类必须实现这些新方法。 <BR>Hibernate3.0提供了ParameterizedType接口，用于更好的重用用户自定义的类型。 <BR>1.1.10 FetchMode类 <BR><BR>FetchMode.LAZY 和 FetchMode.EAGER被废弃。取而代之的分别为FetchMode.SELECT 和FetchMode.JOIN。 <BR><BR>1.1.11 PersistentEnum类 <BR><BR>PersistentEnum被废弃并删除。已经存在的应用应该采用UserType来处理枚举类型。 <BR><BR>1.1.12 对Blob 和Clob的支持 <BR><BR>Hibernate对Blob和Clob实例进行了包装，使得那些拥有Blob或Clob类型的属性的类的实例可以被游离、序列化或反序列化，以及传递到merge()方法中。 <BR><BR>1.1.13 Hibernate中供扩展的API的变化 <BR><BR>org.hibernate.criterion、 org.hibernate.mapping、 org.hibernate.persister和org.hibernate.collection 包的结构和实现发生了重大的变化。多数基于Hibernate <BR>2.1 的应用不依赖于这些包，因此不会被影响。如果你的应用扩展了这些包中的类，那么必须非常小心的对受影响的程序代码进行升级。 <BR><BR>1.2 元数据的变化 <BR><BR>1.2.1 检索策略 <BR><BR>在Hibernate2.1中，lazy属性的默认值为“false”，而在Hibernate3.0中，lazy属性的默认值为“true”。在升级映射文件时，如果原来的映射文件中的有关元素，如&lt;set&gt;、&lt;class&gt;等没有显式设置lazy属性，那么必须把它们都显式的设置为lazy=“true”。如果觉得这种升级方式很麻烦，可以采取另一简单的升级方式：在&lt;hibernate-mapping&gt;元素中设置: default-lazy=“false”。 <BR><BR>1.2.2 对象标识符的映射 <BR><BR>unsaved-value属性是可选的，在多数情况下，Hibernate3.0将把unsaved-value="0" 作为默认值。 <BR><BR>在Hibernate3.0中，当使用自然主键和游离对象时，不再强迫实现Interceptor.isUnsaved()方法。 如果没有设置这个方法，当Hibernate3.0无法区分对象的状态时，会查询数据库，来判断这个对象到底是临时对象，还是游离对象。不过，显式的使用Interceptor.isUnsaved()方法会获得更好的性能，因为这可以减少Hibernate直接访问数据库的次数。 <BR><BR>1.2.3 集合映射 <BR><BR>&lt;index&gt;元素在某些情况下被&lt;list-index&gt;和&lt;map-key&gt;元素替代。此外，Hibernate3.0用&lt;map-key-many-to-many&gt; 元素来替代原来的&lt;key-many-to-many&gt;.元素，用&lt;composite-map-key&gt;元素来替代原来的&lt;composite-index&gt;元素。 <BR><BR>1.2.4 DTD <BR><BR>对象-关系映射文件中的DTD文档，由原来的： <BR><A href="http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" target=_blank><FONT color=#56662d>http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd</FONT></A> <BR>改为： <BR><A href="http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" target=_blank><FONT color=#56662d>http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd</FONT></A> <BR><BR>1.3 查询语句的变化 <BR><BR>Hibernate3.0 采用新的基于ANTLR的HQL/SQL查询翻译器，不过，Hibernate2.1的查询翻译器也依然存在。在Hibernate的配置文件中，hibernate.query.factory_class属性用来选择查询翻译器。例如： <BR>（1）选择Hibernate3.0的查询翻译器： <BR>hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory <BR>（2）选择Hibernate2.1的查询翻译器 <BR>hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory <BR><BR>提示：ANTLR是用纯Java语言编写出来的一个编译工具，它可生成Java语言或者是C++的词法和语法分析器，并可产生语法分析树并对该树进行遍历。ANTLR由于是纯Java的，因此可以安装在任意平台上，但是需要JDK的支持。 <BR>Hibernate开发小组尽力保证Hibernate3.0的查询翻译器能够支持Hibernate2.1的所有查询语句。不过，对于许多已经存在的应用，在升级过程中，也不妨仍然使用Hibernate2.1的查询翻译器。 <BR>值得注意的是， Hibernate3.0的查询翻译器存在一个Bug：不支持某些theta-style连结查询方言：如Oracle8i的OracleDialect方言、Sybase11Dialect。解决这一问题的办法有两种：（1）改为使用支持ANSI-style连结查询的方言，如 Oracle9Dialect,（2）如果升级的时候遇到这一问题，那么还是改为使用Hibernate2.1的查询翻译器。 <BR><BR>1.3.1 indices()和elements()函数 <BR><BR>在HQL的select子句中废弃了indices()和elements()函数，因为这两个函数的语法很让用户费解，可以用显式的连接查询语句来替代 select elements(...) 。而在HQL的where子句中，仍然可以使用elements()函数。 <img src ="http://www.blogjava.net/tangbao/aggbug/32127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/tangbao/" target="_blank">糖包</a> 2006-02-23 17:04 <a href="http://www.blogjava.net/tangbao/articles/32127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>