第 12 章 使用ORM工具进行数据访问

目录

12.1. 简介
12.2. Hibernate
12.2.1. 资源管理
12.2.2. 在Spring的application context中创建 SessionFactory
12.2.3. HibernateTemplate
12.2.4. 不使用回调的基于Spring的DAO实现
12.2.5. 基于Hibernate3的原生API实现DAO
12.2.6. 编程式的事务划分
12.2.7. 声明式的事务划分
12.2.8. 事务管理策略
12.2.9. 容器资源 vs 本地资源
12.2.10. 在应用服务器中使用Hibernate的注意点
12.3. JDO
12.3.1. 建立PersistenceManagerFactory
12.3.2. JdoTemplateJdoDaoSupport
12.3.3. 基于原生的JDO API实现DAO
12.3.4. 事务管理
12.3.5. JdoDialect
12.4. Oracle TopLink
12.4.1. SessionFactory 抽象层
12.4.2. TopLinkTemplateTopLinkDaoSupport
12.4.3. 基于原生的TopLink API的DAO实现
12.4.4. 事务管理
12.5. iBATIS SQL Maps
12.5.1. iBATIS 1.x和2.x的概览与区别
12.5.2. iBATIS SQL Maps 1.x
12.5.3. iBATIS SQL Maps 2.x
12.6. JPA
12.6.1. 在Spring环境中建立JPA
12.6.2. JpaTemplateJpaDaoSupport
12.6.3. 基于原生的JPA实现DAO
12.6.4. 异常转化
12.6.5. 事务管理
12.6.6. JpaDialect

12.1. 简介

Spring在资源管理,DAO实现支持以及事务策略等方面提供了与 Hibernate、JDO、Oracle TopLink、iBATIS SQL Mappings 以及 JPA 的集成。 以Hibernate为例,Spring通过使用许多IoC的便捷特性对它提供了一流的支持,帮助你处理很多典型的Hibernate整合的问题。 所有的这些支持,都遵循Spring通用的事务和DAO异常体系。通常来说有两种不同的整合风格:你可以使用Spring提供的DAO模板,或者直接使用Hibernate/JDO/TopLink等工具的原生API编写DAO。 无论采取哪种风格,这些DAO都可以通过IoC进行配置,并参与到Spring的资源和事务管理中去。

当你选择使用O/R Mapping工具来创建数据访问应用程序的时候,Spring为你提供了重大的支持。 首先你应该了解的是,一旦使用了Spring对O/R Mapping的支持,你不需要亲自做所有的事情。 无论如何,在决定花费力气并冒着风险去构造类似的内部底层架构之前,我们都建议你考虑和使用Spring的解决方案。 无论您采用何种技术,Spring对大部分O/R Mapping的支持都可以以library的形式被调用, 因为所有的内容都被设计成一组可重用的JavaBeans。在Spring的IoC容器中使用这些类,更是有着配置和部署简单的好处。 因而,在这一章中你看到的大多数例子都是在Spring的 ApplicationContext 中进行的配置。

使用Spring构建你的O/R Mapping DAO的好处包括:

  • 测试简单。 Spring的IoC使得替换不同的实现和配置变得非常简单, 这些内容包括:Hibernate SessionFactory 的位置,JDBC DataSource, 事务管理器以及映射对象的实现(如果需要)等。这样也就很容易隔离并测试持久化相关的代码的各个部分。

  • 异常封装。 Spring能够封装你所选择的O/R Mapping工具所抛出的异常, 将它们从专有的、潜在的checked exception转化为一组抽象的runtime DataAccessException体系。 这可以使你仅需要在恰当的应用程序层次去处理大部分不可恢复的持久层异常,从而避免了很多令人讨厌的catch/throw以及异常声明。 当然,你还是可以在你需要的地方捕捉和处理异常。回想一下JDBC异常(包括与DB相关的Dialect)被转变为同样的异常体系,这就意味着你可以在一致的编程模型中处理JDBC操作。

  • 通用的资源管理。 Spring的application context能够处理诸如Hibernate的 SessionFactory, JDBC的 DataSource,iBatis的SQL Maps配置对象以及其他相关资源的定位和配置。 这样,这些配置的值很容易被管理和修改。Spring提供了简单、有效、安全的对持久层资源的处理。 以Hibernate为例,通常在使用Hibernate时,需要使用同一个Hibernate Session 对象以确保高效和恰当地事务处理。 Spring让我们能够很容易透明地创建并绑定一个 Session 到当前线程。 你可以使用以下两种办法之一:通过使用一个外部的template包装类在Java代码层次实现, 或者通过Hibernate的 SessionFactory 暴露当前 Session 对象(对于那些建立在Hibernate3原生的API上的DAO)。 这样,对于任何的事务环境(本地事务或者JTA),Spring解决了许多在Hibernate使用中不断出现的这样那样的问题。

  • 综合的事务管理。 Spring允许你封装你的O/R Mapping代码, 这可以通过声明式的AOP方法拦截器或者在Java代码级别上使用一个外部的template包装类。 无论使用哪一种方式,事务控制都会帮助你做相关处理,例如万一有异常发生时的事务操作(rollback)。 正如我们下面要讨论的一样,你能够使用和替换各种事务管理器,却不会使你的Hibernate/JDO相关的代码受到影响。 例如,不管采用本地事务还是JTA,完整的Service层的代码(如声明式事务管理)在这种场景下都是相同的。 作为一个附加的功能,JDBC相关的代码能够在事务级别上与你所使用的O/R映射代码无缝整合。 这一功能对于那些诸如批量处理、BLOB的操作等并不适合采用O/R Mapping操作的,但是需要与O/R Mapping操作一起参与相同的事务来说是相当有用的。

  • 避免绑定特定技术允许mix-and-match的实现策略。 虽然Hibernate非常强大、灵活、开源而且免费,但它还是使用了自己的特定的API。 此外,有人也许会争辩:iBatis更轻便而且在不需要复杂的O/R映射策略的应用中使用时能够表现得非常优秀。 如果可以选择的话,使用标准或抽象的API来实现主要的应用需求通常是更好的,尤其是当你可能会因为功能、性能或其他方面的原因而需要切换到另一种实现的时候。 举例来说,Spring对Hibernate事务和异常抽象,允许你通过IoC机制轻松封装mapper和DAO对象来实现数据访问功能,这些特性都能够使你在 不牺牲Hibernate强大功能 的情况下在你的应用程序中隔离Hibernate的相关代码。 处理DAO的高层次的service代码无需知道DAO的具体实现。这一机制可以很容易使用mix-and-match方案互不干扰地实现数据访问层(比如在一些地方用Hibernate,一些地方使用JDBC,其他地方使用iBatis), mix-and-match的特性也有利于处理遗留代码并在各种技术(JDBC、Hibernate和iBatis)之间取长补短.

在Spring发布包中的PetClinic提供了各种可选择的DAO实现和application context对JDBC、Hibernate、Oracle TopLink和JPA的配置。 因而PetClinic能够作为一个Spring的web应用示例程序来描述Hibernate、TopLink和JPA的使用方法的。它同时涵盖了声明式事务中不同事务策略的配置。

JPetStore示例主要举例说明了iBATIS SQL Map在Spring环境中的使用。它同时包含了两套不同的Web层选择,一套基于Spring Web MVC,而另外一套则基于Struts。

除了Spring自身提供的示例之外,有很多其他的基于Spring的O/R Mapping的示例,他们由各自的供应商提供。 例如:JDO的JPOX实现(http://www.jpox.org/)以及Kodo(http://www.bea.com/kodo)。