CSDN 推薦tag:api?com?hibernate?ice?java?os?sql?函數(shù)?軟件?
選自《精通Hibernate:Java對(duì)象持久化技術(shù)詳解》?作者:孫衛(wèi)琴?來(lái)源:?www.javathinker.org?
如果轉(zhuǎn)載,請(qǐng)標(biāo)明出處,謝謝?

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?對(duì)Blob?和Clob的支持?
1.1.13?Hibernate中供擴(kuò)展的API的變化?
1.2?元數(shù)據(jù)的變化?
1.2.1?檢索策略?
1.2.2?對(duì)象標(biāo)識(shí)符的映射?
1.2.3?集合映射?
1.2.4?DTD?
1.3?查詢語(yǔ)句的變化?
1.3.1?indices()和elements()函數(shù)?


盡管Hibernate?3.0?與Hibernate2.1的源代碼是不兼容的,但是當(dāng)Hibernate開(kāi)發(fā)小組在設(shè)計(jì)Hibernate3.0時(shí),為簡(jiǎn)化升級(jí)Hibernate版本作了周到的考慮。對(duì)于現(xiàn)有的基于Hibernate2.1的Java項(xiàng)目,可以很方便的把它升級(jí)到Hibernate3.0。?

本文描述了Hibernate3.0版本的新變化,Hibernate3.0版本的變化包括三個(gè)方面:?
(1)API的變化,它將影響到Java程序代碼。?
(2)元數(shù)據(jù),它將影響到對(duì)象-關(guān)系映射文件。?
(3)HQL查詢語(yǔ)句。?

值得注意的是,?Hibernate3.0并不會(huì)完全取代Hibernate2.1。在同一個(gè)應(yīng)用程序中,允許Hibernate3.0和Hibernate2.1并存。?

1.1?Hibernate?API?變化?

1.1.1?包名?

Hibernate3.0的包的根路徑為:?“org.hibernate”?,而在Hibernate2.1中為“net.sf.hibernate”。這一命名變化使得Hibernate2.1和Hibernate3.0能夠同時(shí)在同一個(gè)應(yīng)用程序中運(yùn)行。?

如果希望把已有的應(yīng)用升級(jí)到Hibernate3.0,那么升級(jí)的第一步是把Java源程序中的所有“net.sf.hibernate”替換為“org.hibernate”。?

Hibernate2.1中的“net.sf.hibernate.expression”包被改名為“org.hibernate.criterion”。假如應(yīng)用程序使用了Criteria?API,那么在升級(jí)的過(guò)程中,必須把Java源程序中的所有“net.sf.hibernate.expression”替換為“org.hibernate.criterion”。?

如果應(yīng)用使用了除Hibernate以外的其他外部軟件,而這個(gè)外部軟件又引用了Hibernate的接口,那么在升級(jí)時(shí)必須十分小心。例如EHCache擁有自己的CacheProvider:?net.sf.ehcache.hibernate.Provider,在這個(gè)類中引用了Hibernate2.1中的接口,在升級(jí)應(yīng)用時(shí),可以采用以下辦法之一來(lái)升級(jí)EHCache:?

(1)手工修改net.sf.ehcache.hibernate.Provider類,使它引用Hibernate3.0中的接口。?
(2)等到EHCache軟件本身升級(jí)為使用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。因此在編譯時(shí),編譯器不會(huì)再檢查HibernateException。?

1.1.5?Session接口?

在Hibernate3.0中,原來(lái)Hibernate2.1的Session接口中的有些基本方法也被廢棄,但為了簡(jiǎn)化升級(jí),這些方法依然是可用的,可以通過(guò)org.hibernate.classic.Session子接口來(lái)訪問(wèn)它們,例如:?
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類型的實(shí)例。如果希望在程序中完全使用Hibernate3.0,可以采用以下方式創(chuàng)建Session實(shí)例:?

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

如果是對(duì)已有的程序進(jìn)行簡(jiǎn)單的升級(jí),并且希望仍然調(diào)用Hibernate2.1中Session的一些接口,可以采用以下方式創(chuàng)建Session實(shí)例:?

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

在Hibernate3.0中,Session接口中被廢棄的方法包括:?
*?執(zhí)行查詢的方法:find()、iterate()、filter()和delete(String?hqlSelectQuery)?
*?saveOrUpdateCopy()?

Hibernate3.0一律采用createQuery()方法來(lái)執(zhí)行所有的查詢語(yǔ)句,采用DELETE?查詢語(yǔ)句來(lái)執(zhí)行批量刪除,采用merge()方法來(lái)替代?saveOrUpdateCopy()方法。?

提示:在Hibernate2.1中,Session的delete()方法有幾種重載形式,其中參數(shù)為HQL查詢語(yǔ)句的delete()方法在Hibernate3.0中被廢棄,而參數(shù)為Ojbect類型的的delete()方法依然被支持。delete(Object?o)方法用于刪除參數(shù)指定的對(duì)象,該方法支持級(jí)聯(lián)刪除。?
Hibernate2.1沒(méi)有對(duì)批量更新和批量刪除提供很好的支持,參見(jiàn)<<精通Hibernate>>一書(shū)的第13章的13.1.1節(jié)(批量更新和批量刪除),而Hibernate3.0對(duì)批量更新和批量刪除提供了支持,能夠直接執(zhí)行批量更新或批量刪除語(yǔ)句,無(wú)需把被更新或刪除的對(duì)象先加載到內(nèi)存中。以下是通過(guò)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();?
以下是通過(guò)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接口來(lái)完成相同的功能。?

1.1.7?Lifecycle?和?Validatable?接口?

Lifecycle和Validatable?接口被廢棄,并且被移到org.hibernate.classic包中。?

1.1.8?Interceptor接口?

在Interceptor?接口中加入了兩個(gè)新的方法。?用戶創(chuàng)建的Interceptor實(shí)現(xiàn)類在升級(jí)的過(guò)程中,需要為這兩個(gè)新方法提供方法體為空的實(shí)現(xiàn)。此外,instantiate()方法的參數(shù)作了修改,isUnsaved()方法被改名為isTransient()。?

1.1.9?UserType和CompositeUserType接口?

在UserType和CompositeUserType接口中都加入了一些新的方法,這兩個(gè)接口被移到org.hibernate.usertype包中,用戶定義的UserType和CompositeUserType實(shí)現(xiàn)類必須實(shí)現(xiàn)這些新方法。?
Hibernate3.0提供了ParameterizedType接口,用于更好的重用用戶自定義的類型。?
1.1.10?FetchMode類?

FetchMode.LAZY?和?FetchMode.EAGER被廢棄。取而代之的分別為FetchMode.SELECT?和FetchMode.JOIN。?

1.1.11?PersistentEnum類?

PersistentEnum被廢棄并刪除。已經(jīng)存在的應(yīng)用應(yīng)該采用UserType來(lái)處理枚舉類型。?

1.1.12?對(duì)Blob?和Clob的支持?

Hibernate對(duì)Blob和Clob實(shí)例進(jìn)行了包裝,使得那些擁有Blob或Clob類型的屬性的類的實(shí)例可以被游離、序列化或反序列化,以及傳遞到merge()方法中。?

1.1.13?Hibernate中供擴(kuò)展的API的變化?

org.hibernate.criterion、?org.hibernate.mapping、?org.hibernate.persister和org.hibernate.collection?包的結(jié)構(gòu)和實(shí)現(xiàn)發(fā)生了重大的變化。多數(shù)基于Hibernate?
2.1?的應(yīng)用不依賴于這些包,因此不會(huì)被影響。如果你的應(yīng)用擴(kuò)展了這些包中的類,那么必須非常小心的對(duì)受影響的程序代碼進(jìn)行升級(jí)。?

1.2?元數(shù)據(jù)的變化?

1.2.1?檢索策略?

在Hibernate2.1中,lazy屬性的默認(rèn)值為“false”,而在Hibernate3.0中,lazy屬性的默認(rèn)值為“true”。在升級(jí)映射文件時(shí),如果原來(lái)的映射文件中的有關(guān)元素,如、等沒(méi)有顯式設(shè)置lazy屬性,那么必須把它們都顯式的設(shè)置為lazy=“true”。如果覺(jué)得這種升級(jí)方式很麻煩,可以采取另一簡(jiǎn)單的升級(jí)方式:在元素中設(shè)置:?default-lazy=“false”。?

1.2.2?對(duì)象標(biāo)識(shí)符的映射?

unsaved-value屬性是可選的,在多數(shù)情況下,Hibernate3.0將把unsaved-value="0"?作為默認(rèn)值。?

在Hibernate3.0中,當(dāng)使用自然主鍵和游離對(duì)象時(shí),不再?gòu)?qiáng)迫實(shí)現(xiàn)Interceptor.isUnsaved()方法。?如果沒(méi)有設(shè)置這個(gè)方法,當(dāng)Hibernate3.0無(wú)法區(qū)分對(duì)象的狀態(tài)時(shí),會(huì)查詢數(shù)據(jù)庫(kù),來(lái)判斷這個(gè)對(duì)象到底是臨時(shí)對(duì)象,還是游離對(duì)象。不過(guò),顯式的使用Interceptor.isUnsaved()方法會(huì)獲得更好的性能,因?yàn)檫@可以減少Hibernate直接訪問(wèn)數(shù)據(jù)庫(kù)的次數(shù)。?

1.2.3?集合映射?

元素在某些情況下被和元素替代。此外,Hibernate3.0用?元素來(lái)替代原來(lái)的.元素,用元素來(lái)替代原來(lái)的元素。?

1.2.4?DTD?

對(duì)象-關(guān)系映射文件中的DTD文檔,由原來(lái)的:?
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd?
改為:?
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd?

1.3?查詢語(yǔ)句的變化?

Hibernate3.0?采用新的基于ANTLR的HQL/SQL查詢翻譯器,不過(guò),Hibernate2.1的查詢翻譯器也依然存在。在Hibernate的配置文件中,hibernate.query.factory_class屬性用來(lái)選擇查詢翻譯器。例如:?
(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語(yǔ)言編寫出來(lái)的一個(gè)編譯工具,它可生成Java語(yǔ)言或者是C++的詞法和語(yǔ)法分析器,并可產(chǎn)生語(yǔ)法分析樹(shù)并對(duì)該樹(shù)進(jìn)行遍歷。ANTLR由于是純Java的,因此可以安裝在任意平臺(tái)上,但是需要JDK的支持。?
Hibernate開(kāi)發(fā)小組盡力保證Hibernate3.0的查詢翻譯器能夠支持Hibernate2.1的所有查詢語(yǔ)句。不過(guò),對(duì)于許多已經(jīng)存在的應(yīng)用,在升級(jí)過(guò)程中,也不妨仍然使用Hibernate2.1的查詢翻譯器。?
值得注意的是,?Hibernate3.0的查詢翻譯器存在一個(gè)Bug:不支持某些theta-style連結(jié)查詢方言:如Oracle8i的OracleDialect方言、Sybase11Dialect。解決這一問(wèn)題的辦法有兩種:(1)改為使用支持ANSI-style連結(jié)查詢的方言,如?Oracle9Dialect,(2)如果升級(jí)的時(shí)候遇到這一問(wèn)題,那么還是改為使用Hibernate2.1的查詢翻譯器。?

1.3.1?indices()和elements()函數(shù)?

在HQL的select子句中廢棄了indices()和elements()函數(shù),因?yàn)檫@兩個(gè)函數(shù)的語(yǔ)法很讓用戶費(fèi)解,可以用顯式的連接查詢語(yǔ)句來(lái)替代?select?elements(...)?。而在HQL的where子句中,仍然可以使用elements()函數(shù)。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=623674