随笔 - 6  文章 - 0  trackbacks - 0
<2026年11月>
日一二三四五六
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(2)

随笔分类

文章分类

好友

搜索

  •  

最新评论

阅读排行榜

评论排行榜

如何把 Hibernate2.1 升级到 Hibernate3.0 ?
选自 << 精通 Hibernate : Java 对象持久化技术详解 >> 作者:孙卫琴 来源 :www.javathinker.org
如果转载,请标明出处,谢谢

1.1 Hibernate API
变化
1.1.1
包名
1.1.2 org.hibernate.classic
包
1.1.3 Hibernate
所依赖的第三方软件包
1.1.4
异常模型
1.1.5 Session
接口
1.1.6 createSQLQuery()
1.1.7 Lifecycle
和 Validatable 接口
1.1.8 Interceptor
接口
1.1.9 UserType
和 CompositeUserType 接口
1.1.10 FetchMode
类
1.1.11 PersistentEnum
类
1.1.12
对 Blob 和 Clob 的支持
1.1.13 Hibernate
中供扩展的 API 的变化
1.2
元数据的变化
1.2.1
检索策略
1.2.2
对象标识符的映射
1.2.3
集合映射
1.2.4 DTD
1.3
查询语句的变化
1.3.1 indices()
和 elements() 函数

尽管 Hibernate 3.0 与 Hibernate2.1 的源代码是不兼容的,但是当 Hibernate 开发小组在设计 Hibernate3.0 时,为简化升级 Hibernate 版本作了周到的考虑。对于现有的基于 Hibernate2.1 的 Java 项目,可以很方便的把它升级到 Hibernate3.0 。

本文描述了 Hibernate3.0 版本的新变化, Hibernate3.0 版本的变化包括三个方面:
( 1 ) API 的变化,它将影响到 Java 程序代码。
( 2 )元数据,它将影响到对象 - 关系映射文件。
( 3 ) HQL 查询语句。

值得注意的是, Hibernate3.0 并不会完全取代 Hibernate2.1 。在同一个应用程序中,允许 Hibernate3.0 和 Hibernate2.1 并存。

1.1 Hibernate API
变化

1.1.1
包名

Hibernate3.0
的包的根路径为 : “org.hibernate” ,而在 Hibernate2.1 中为 “net.sf.hibernate” 。这一命名变化使得 Hibernate2.1 和 Hibernate3.0 能够同时在同一个应用程序中运行。

如果希望把已有的应用升级到 Hibernate3.0 ,那么升级的第一步是把 Java 源程序中的所有 “net.sf.hibernate” 替换为 “org.hibernate” 。

Hibernate2.1
中的 “net.sf.hibernate.expression” 包被改名为 “org.hibernate.criterion” 。假如应用程序使用了 Criteria API ,那么在升级的过程中,必须把 Java 源程序中的所有 “net.sf.hibernate.expression” 替换为 “org.hibernate.criterion” 。

如果应用使用了除 Hibernate 以外的其他外部软件,而这个外部软件又引用了 Hibernate 的接口,那么在升级时必须十分小心。例如 EHCache 拥有自己的 CacheProvider : net.sf.ehcache.hibernate.Provider ,在这个类中引用了 Hibernate2.1 中的接口,在升级应用时,可以采用以下办法之一来升级 EHCache:

( 1 )手工修改 net.sf.ehcache.hibernate.Provider 类,使它引用 Hibernate3.0 中的接口。
( 2 )等到 EHCache 软件本身升级为使用 Hibernate3.0 后,使用新的 EHCache 软件。
( 3 )使用 Hibernate3.0 中内置的 CacheProvider : org.hibernate.cache.EhCacheProvider 。

1.1.2 org.hibernate.classic
包

Hibernate3.0
把一些被废弃的接口都转移到 org.hibernate.classic 中。

1.1.3 Hibernate
所依赖的第三方软件包

在 Hibernate3.0 的软件包的 lib 目录下的 README.txt 文件中,描述了 Hibernate3.0 所依赖的第三方软件包的变化。

1.1.4
异常模型

在 Hibernate3.0 中, HibernateException 异常以及它的所有子类都继承了 java.lang.RuntimeException 。因此在编译时,编译器不会再检查 HibernateException 。

1.1.5 Session
接口

在 Hibernate3.0 中,原来 Hibernate2.1 的 Session 接口中的有些基本方法也被废弃,但为了简化升级,这些方法依然是可用的,可以通过 org.hibernate.classic.Session 子接口来访问它们,例如:
org.hibernate.classic.Session session=sessionFactory.openSession();
session.delete("delete from Customer ");
在 Hibernate3.0 中, org.hibernate.classic.Session 接口继承了 org.hibernate.Session 接口,在 org.hibernate.classic.Session 接口中包含了一系列被废弃的方法,如 find() 、 interate() 等。 SessionFactory 接口的 openSession() 方法返回 org.hibernate.classic.Session 类型的实例。如果希望在程序中完全使用 Hibernate3.0 ,可以采用以下方式创建 Session 实例:

org.hibernate.Session session=sessionFactory.openSession();

如果是对已有的程序进行简单的升级,并且希望仍然调用 Hibernate2.1 中 Session 的一些接口,可以采用以下方式创建 Session 实例:

org.hibernate.classic.Session session=sessionFactory.openSession();

在 Hibernate3.0 中, Session 接口中被废弃的方法包括:
*
执行查询的方法: find() 、 iterate() 、 filter() 和 delete(String hqlSelectQuery)
* saveOrUpdateCopy()

Hibernate3.0
一律采用 createQuery() 方法来执行所有的查询语句,采用 DELETE 查询语句来执行批量删除,采用 merge() 方法来替代 saveOrUpdateCopy() 方法。

提示:在 Hibernate2.1 中, Session 的 delete() 方法有几种重载形式,其中参数为 HQL 查询语句的 delete() 方法在 Hibernate3.0 中被废弃,而参数为 Ojbect 类型的的 delete() 方法依然被支持。 delete(Object o) 方法用于删除参数指定的对象,该方法支持级联删除。
Hibernate2.1
没有对批量更新和批量删除提供很好的支持,参见 << 精通 Hibernate>> 一书的第 13 章的 13.1.1 节(批量更新和批量删除),而 Hibernate3.0 对批量更新和批量删除提供了支持,能够直接执行批量更新或批量删除语句,无需把被更新或删除的对象先加载到内存中。以下是通过 Hibernate3.0 执行批量更新的程序代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "update Customer set name = :newName where name = :oldName";
int updatedEntities = s.createQuery( hqlUpdate )
.setString( "newName", newName )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();
以下是通过 Hibernate3.0 执行批量删除的程序代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlDelete = "delete Customer where name = :oldName";
int deletedEntities = s.createQuery( hqlDelete )
.setString( "oldName", oldName )
.executeUpdate();
tx.commit();
session.close();

1.1.6 createSQLQuery()

在 Hibernate3.0 中, Session 接口的 createSQLQuery() 方法被废弃,被移到 org.hibernate.classic.Session 接口中。 Hibernate3.0 采用新的 SQLQuery 接口来完成相同的功能。

1.1.7 Lifecycle
和 Validatable 接口

Lifecycle
和 Validatable 接口被废弃,并且被移到 org.hibernate.classic 包中。

1.1.8 Interceptor
接口

在 Interceptor 接口中加入了两个新的方法。 用户创建的 Interceptor 实现类在升级的过程中,需要为这两个新方法提供方法体为空的实现。此外, instantiate() 方法的参数作了修改, isUnsaved() 方法被改名为 isTransient() 。

1.1.9 UserType
和 CompositeUserType 接口

在 UserType 和 CompositeUserType 接口中都加入了一些新的方法,这两个接口被移到 org.hibernate.usertype 包中,用户定义的 UserType 和 CompositeUserType 实现类必须实现这些新方法。
Hibernate3.0
提供了 ParameterizedType 接口,用于更好的重用用户自定义的类型。
1.1.10 FetchMode
类

FetchMode.LAZY
和 FetchMode.EAGER 被废弃。取而代之的分别为 FetchMode.SELECT 和 FetchMode.JOIN 。

1.1.11 PersistentEnum
类

PersistentEnum
被废弃并删除。已经存在的应用应该采用 UserType 来处理枚举类型。

1.1.12
对 Blob 和 Clob 的支持

Hibernate
对 Blob 和 Clob 实例进行了包装,使得那些拥有 Blob 或 Clob 类型的属性的类的实例可以被游离、序列化或反序列化,以及传递到 merge() 方法中。

1.1.13 Hibernate
中供扩展的 API 的变化

org.hibernate.criterion
、 org.hibernate.mapping 、 org.hibernate.persister 和 org.hibernate.collection 包的结构和实现发生了重大的变化。多数基于 Hibernate
2.1
的应用不依赖于这些包,因此不会被影响。如果你的应用扩展了这些包中的类,那么必须非常小心的对受影响的程序代码进行升级。

1.2
元数据的变化

1.2.1
检索策略

在 Hibernate2.1 中, lazy 属性的默认值为 “false” ,而在 Hibernate3.0 中, lazy 属性的默认值为 “true” 。在升级映射文件时,如果原来的映射文件中的有关元素,如 <set> 、 <class> 等没有显式设置 lazy 属性,那么必须把它们都显式的设置为 lazy=“true” 。如果觉得这种升级方式很麻烦,可以采取另一简单的升级方式:在 <hibernate-mapping> 元素中设置 : default-lazy=“false” 。

1.2.2
对象标识符的映射

unsaved-value
属性是可选的,在多数情况下, Hibernate3.0 将把 unsaved-value="0" 作为默认值。

在 Hibernate3.0 中,当使用自然主键和游离对象时,不再强迫实现 Interceptor.isUnsaved() 方法。 如果没有设置这个方法,当 Hibernate3.0 无法区分对象的状态时,会查询数据库,来判断这个对象到底是临时对象,还是游离对象。不过,显式的使用 Interceptor.isUnsaved() 方法会获得更好的性能,因为这可以减少 Hibernate 直接访问数据库的次数。

1.2.3
集合映射

<index>
元素在某些情况下被 <list-index> 和 <map-key> 元素替代。此外, Hibernate3.0 用 <map-key-many-to-many> 元素来替代原来的 <key-many-to-many>. 元素,用 <composite-map-key> 元素来替代原来的 <composite-index> 元素。

1.2.4 DTD

对象 - 关系映射文件中的 DTD 文档,由原来的:
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd
改为:
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd

1.3
查询语句的变化

Hibernate3.0
采用新的基于 ANTLR 的 HQL/SQL 查询翻译器,不过, Hibernate2.1 的查询翻译器也依然存在。在 Hibernate 的配置文件中, hibernate.query.factory_class 属性用来选择查询翻译器。例如:
( 1 )选择 Hibernate3.0 的查询翻译器:
hibernate.query.factory_class= org.hibernate.hql.ast.ASTQueryTranslatorFactory
( 2 )选择 Hibernate2.1 的查询翻译器
hibernate.query.factory_class= org.hibernate.hql.classic.ClassicQueryTranslatorFactory

提示: ANTLR 是用纯 Java 语言编写出来的一个编译工具,它可生成 Java 语言或者是 C++ 的词法和语法分析器,并可产生语法分析树并对该树进行遍历。 ANTLR 由于是纯 Java 的,因此可以安装在任意平台上,但是需要 JDK 的支持。
Hibernate
开发小组尽力保证 Hibernate3.0 的查询翻译器能够支持 Hibernate2.1 的所有查询语句。不过,对于许多已经存在的应用,在升级过程中,也不妨仍然使用 Hibernate2.1 的查询翻译器。
值得注意的是, Hibernate3.0 的查询翻译器存在一个 Bug :不支持某些 theta-style 连结查询方言:如 Oracle8i 的 OracleDialect 方言、 Sybase11Dialect 。解决这一问题的办法有两种:( 1 )改为使用支持 ANSI-style 连结查询的方言,如 Oracle9Dialect, ( 2 )如果升级的时候遇到这一问题,那么还是改为使用 Hibernate2.1 的查询翻译器。

1.3.1 indices()
和 elements() 函数

在 HQL 的 select 子句中废弃了 indices() 和 elements() 函数,因为这两个函数的语法很让用户费解,可以用显式的连接查询语句来替代 select elements(...) 。而在 HQL 的 where 子句中,仍然可以使用 elements() 函数。

posted on 2006-05-01 21:13 badboy 阅读(460) 评论(0)  编辑  收藏 所属分类: Framework