如何把
Hibernate2.1
升級到
Hibernate3.0
?
選自
<<
精通
Hibernate
:
Java
對象持久化技術(shù)詳解
>>
作者:孫衛(wèi)琴
來源
:www.javathinker.org
如果轉(zhuǎn)載,請標明出處,謝謝
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
元數(shù)據(jù)的變化
1.2.1
檢索策略
1.2.2
對象標識符的映射
1.2.3
集合映射
1.2.4 DTD
1.3
查詢語句的變化
1.3.1 indices()
和
elements()
函數(shù)
盡管
Hibernate 3.0
與
Hibernate2.1
的源代碼是不兼容的,但是當
Hibernate
開發(fā)小組在設計
Hibernate3.0
時,為簡化升級
Hibernate
版本作了周到的考慮。對于現(xiàn)有的基于
Hibernate2.1
的
Java
項目,可以很方便的把它升級到
Hibernate3.0
。
本文描述了
Hibernate3.0
版本的新變化,
Hibernate3.0
版本的變化包括三個方面:
(
1
)
API
的變化,它將影響到
Java
程序代碼。
(
2
)元數(shù)據(jù),它將影響到對象
-
關系映射文件。
(
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
中內(nèi)置的
CacheProvider
:
org.hibernate.cache.EhCacheProvider
。
1.1.2 org.hibernate.classic
包
Hibernate3.0
把一些被廢棄的接口都轉(zhuǎn)移到
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
,可以采用以下方式創(chuàng)建
Session
實例:
org.hibernate.Session session=sessionFactory.openSession();
如果是對已有的程序進行簡單的升級,并且希望仍然調(diào)用
Hibernate2.1
中
Session
的一些接口,可以采用以下方式創(chuàng)建
Session
實例:
org.hibernate.classic.Session session=sessionFactory.openSession();
在
Hibernate3.0
中,
Session
接口中被廢棄的方法包括:
*
執(zhí)行查詢的方法:
find()
、
iterate()
、
filter()
和
delete(String hqlSelectQuery)
* saveOrUpdateCopy()
Hibernate3.0
一律采用
createQuery()
方法來執(zhí)行所有的查詢語句,采用
DELETE
查詢語句來執(zhí)行批量刪除,采用
merge()
方法來替代
saveOrUpdateCopy()
方法。
提示:在
Hibernate2.1
中,
Session
的
delete()
方法有幾種重載形式,其中參數(shù)為
HQL
查詢語句的
delete()
方法在
Hibernate3.0
中被廢棄,而參數(shù)為
Ojbect
類型的的
delete()
方法依然被支持。
delete(Object o)
方法用于刪除參數(shù)指定的對象,該方法支持級聯(lián)刪除。
Hibernate2.1
沒有對批量更新和批量刪除提供很好的支持,參見
<<
精通
Hibernate>>
一書的第
13
章的
13.1.1
節(jié)(批量更新和批量刪除),而
Hibernate3.0
對批量更新和批量刪除提供了支持,能夠直接執(zhí)行批量更新或批量刪除語句,無需把被更新或刪除的對象先加載到內(nèi)存中。以下是通過
Hibernate3.0
執(zhí)行批量更新的程序代碼:
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
執(zhí)行批量刪除的程序代碼:
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
接口中加入了兩個新的方法。
用戶創(chuàng)建的
Interceptor
實現(xiàn)類在升級的過程中,需要為這兩個新方法提供方法體為空的實現(xiàn)。此外,
instantiate()
方法的參數(shù)作了修改,
isUnsaved()
方法被改名為
isTransient()
。
1.1.9 UserType
和
CompositeUserType
接口
在
UserType
和
CompositeUserType
接口中都加入了一些新的方法,這兩個接口被移到
org.hibernate.usertype
包中,用戶定義的
UserType
和
CompositeUserType
實現(xiàn)類必須實現(xiàn)這些新方法。
Hibernate3.0
提供了
ParameterizedType
接口,用于更好的重用用戶自定義的類型。
1.1.10 FetchMode
類
FetchMode.LAZY
和
FetchMode.EAGER
被廢棄。取而代之的分別為
FetchMode.SELECT
和
FetchMode.JOIN
。
1.1.11 PersistentEnum
類
PersistentEnum
被廢棄并刪除。已經(jīng)存在的應用應該采用
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
包的結(jié)構(gòu)和實現(xiàn)發(fā)生了重大的變化。多數(shù)基于
Hibernate
2.1
的應用不依賴于這些包,因此不會被影響。如果你的應用擴展了這些包中的類,那么必須非常小心的對受影響的程序代碼進行升級。
1.2
元數(shù)據(jù)的變化
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
屬性是可選的,在多數(shù)情況下,
Hibernate3.0
將把
unsaved-value="0"
作為默認值。
在
Hibernate3.0
中,當使用自然主鍵和游離對象時,不再強迫實現(xiàn)
Interceptor.isUnsaved()
方法。
如果沒有設置這個方法,當
Hibernate3.0
無法區(qū)分對象的狀態(tài)時,會查詢數(shù)據(jù)庫,來判斷這個對象到底是臨時對象,還是游離對象。不過,顯式的使用
Interceptor.isUnsaved()
方法會獲得更好的性能,因為這可以減少
Hibernate
直接訪問數(shù)據(jù)庫的次數(shù)。
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++
的詞法和語法分析器,并可產(chǎn)生語法分析樹并對該樹進行遍歷。
ANTLR
由于是純
Java
的,因此可以安裝在任意平臺上,但是需要
JDK
的支持。
Hibernate
開發(fā)小組盡力保證
Hibernate3.0
的查詢翻譯器能夠支持
Hibernate2.1
的所有查詢語句。不過,對于許多已經(jīng)存在的應用,在升級過程中,也不妨仍然使用
Hibernate2.1
的查詢翻譯器。
值得注意的是,
Hibernate3.0
的查詢翻譯器存在一個
Bug
:不支持某些
theta-style
連結(jié)查詢方言:如
Oracle8i
的
OracleDialect
方言、
Sybase11Dialect
。解決這一問題的辦法有兩種:(
1
)改為使用支持
ANSI-style
連結(jié)查詢的方言,如
Oracle9Dialect,
(
2
)如果升級的時候遇到這一問題,那么還是改為使用
Hibernate2.1
的查詢翻譯器。
1.3.1 indices()
和
elements()
函數(shù)
在
HQL
的
select
子句中廢棄了
indices()
和
elements()
函數(shù),因為這兩個函數(shù)的語法很讓用戶費解,可以用顯式的連接查詢語句來替代
select elements(...)
。而在
HQL
的
where
子句中,仍然可以使用
elements()
函數(shù)。
posted on 2006-05-01 21:13
badboy 閱讀(397)
評論(0) 編輯 收藏 所屬分類:
Framework