實體關(guān)系映射(O/R mapping, ORM)集成
當然你經(jīng)常需要使用實體關(guān)系映射,而不是使用關(guān)系型數(shù)據(jù)訪問。你的整體應用程序框架也必須支持這個。因而Spring繼承了Hibernate(版本2 和3)、JDO(版本1 和2)、TopLink和其他ORM產(chǎn)品。他的數(shù)據(jù)訪問架構(gòu)允許與任何底層數(shù)據(jù)訪問技術(shù)集成。Spring和Hibernate是一個相當流行的組合。
為什么你要用一個ORM產(chǎn)品加上Spring,而不是直接使用它呢?Spring在以下方面增加了重要價值:
會話管理。Spring提供了對諸如Hibernate或Toplink 會話的有效、簡單而且安全的處理。相關(guān)的單獨使用ORM工具的代碼通常需要使用同一個“Session”對象來達到有效且合的事務(wù)處理。Spring能使用一個聲明性的AOP方法攔截器或使用顯式的Java 代碼級的“模板”封裝類來透明創(chuàng)建一個會話并將其綁定到當前線程。因而Spring解決了許多影響ORM 技術(shù)用戶的使用問題。
資源管理。Spring應用程序上下文能處理Hibernate SessionFactory、JDBC數(shù)據(jù)源和其他相關(guān)資源的定位和配置。這使得這些值易于管理和更改。
完整的事務(wù)管理。Spring允許你將你的ORM代碼封裝為一個聲明性的AOP方法攔截器或者一個顯式的Java 代碼級的“模板”封裝類。不管哪種情況,事務(wù)語義都為你處理了,并且在異常發(fā)生時也作了恰當?shù)氖聞?wù)處理(回滾等)。正如我們后面討論的,你也可以使用并切換不同事務(wù)管理器而不影響你的ORM相關(guān)代碼,并從中獲益。一個額外的好處是為了支持大多數(shù)ORM工具JDBC相關(guān)代碼能完全事務(wù)性地與ORM代碼集成。這對于處理ORM沒有實現(xiàn)的功能時很有用。
如上所述的異常封裝。Spring能封裝來自O(shè)RM層的異常,將它們從私有(可能是經(jīng)過檢查的)異常轉(zhuǎn)換為一組抽象的運行時異常。這允許你可以不用煩人的樣板化的catch/throw和異常聲明仍能在恰當?shù)膶又刑幚泶蠖鄶?shù)不可恢復的持久化異常。你仍能在任何需要的地方捕獲和處理異常。請記住JDBC異常(包括數(shù)據(jù)庫特有方言)也被轉(zhuǎn)換為相同層次,這意味著你能在一致的編程模型內(nèi)用JDBC執(zhí)行一些操作。
避免和廠商綁定。ORM解決方案有不同的性能和特性,沒有能滿足所有情況的完美解決方案。作為選擇,你會發(fā)現(xiàn)某一個功能正好不匹配你用的ORM工具的一個實現(xiàn)。這讓你意識到你的數(shù)據(jù)訪問對象接口的特定工具實現(xiàn)對你的架構(gòu)有影響。一旦你因為功能、性能或其他原因需要切換到另一個實現(xiàn),現(xiàn)在使用了Spring讓終的切換變得更容易了。Spring對你ORM工具的事務(wù)和異常的抽象,和它的IoC方法一起讓你在映射器/DAO 對象實現(xiàn)數(shù)據(jù)訪問功能間輕松切換,簡單地實現(xiàn)將ORM特有代碼控制在你應用程序的一個范圍里而不犧牲你ORM工具的能力。和Spring一起發(fā)布的寵物醫(yī)院范例程序演示了Spring通過提供使用JDBC、Hibernate、TopLink和Apache OJB實現(xiàn)的不同持久層而帶來的可移植性方面的價值。
簡化測試。Spring的控制反轉(zhuǎn)方法使得切換實現(xiàn)和諸如Hibernate會話工廠、數(shù)據(jù)源、事務(wù)管理器和映射器對象實現(xiàn)(如果需要)之類的資源位置變得簡單了。這簡化了隔離和每部分持久化相關(guān)代碼的單獨測試。
綜上所述,Spring讓混用數(shù)據(jù)存取過程更簡單了。盡管ORM在很多案例里贏得了頗有價值的生產(chǎn)力,無論一些ORM廠商怎么宣稱,ORM不是所有問題的解決方案。即使你混用各種持久化方法,即使你不用JTA,Spring仍能提供一致的架構(gòu)和事務(wù)策略。
在ORM并不理想的地方,Spring的簡化JDBC并不是選擇:iBATIS SQL Maps 提供的“映射語句”也值得一看。它在保持自動從查詢結(jié)果中創(chuàng)建映射對象的同時提供了對SQL的高層控制。Spring集成了SQL Maps。Spring的寵物店范例程序演示了iBATIS集成。
事務(wù)管理
僅抽象一個數(shù)據(jù)訪問API是不夠的;我們還需要考慮事務(wù)管理。JTA是當然的解決方案,但直接使用它的API是很笨重的,因而許多J2EE 開發(fā)者曾覺得EJB CMT是事務(wù)管理的明智的選擇。Spring改變了這一點。
Spring提供了它自己的針對事務(wù)管理的抽象。Spring 使用它來提供:
通過一個類似JdbcTemplate的回調(diào)模板來實現(xiàn)可編程的事務(wù)管理,比起直接使用JTA容易許多。
類似EJB CMT的聲明性事務(wù)管理,但不需要EJB容器。實際上,正如我們所見,Spring的聲明性事務(wù)管理能力是EJB CMT語義上的超集,有些獨特的重要的好處。
Spring的事務(wù)抽象的獨特之處在于它不綁定于JTA或其他任何事務(wù)管理技術(shù)。Spring使用事務(wù)策略概念,這減弱了底層事務(wù)基礎(chǔ)部分(例如JDBC)對應用程序代碼的影響。
為什么你需要關(guān)心這個?JTA不是對所有事務(wù)管理問題的好答案嗎?如果你正在寫一個只與一個數(shù)據(jù)庫打交道的應用程序,你不需要JTA的復雜性。你不關(guān)心XA事務(wù)或兩階段提交。你甚至可以不需要一個提供這些東西的高端應用服務(wù)器。但另一方面,你不會愿意在和多個數(shù)據(jù)源打交道時重寫你的代碼。