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