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

目录

12.1. 简介
12.2. Hibernate
12.2.1. 资源管理
12.2.2. 在Spring容器中创建 SessionFactory
12.2.3. The 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. TopLinkTemplate and TopLinkDaoSupport
12.4.3. 基于原生的TopLink API的DAO实现
12.4.4. 事务管理
12.5. iBATIS SQL Maps
12.5.1. 创建SqlMapClient
12.5.2. 使用 SqlMapClientTemplateSqlMapClientDaoSupport
12.5.3. 基于原生的iBATIS API的DAO实现
12.6. JPA
12.6.1. 在Spring环境中建立JPA
12.6.2. JpaTemplateJpaDaoSupport
12.6.3. 基于原生的JPA实现DAO
12.6.4. 异常转化
12.7. 事务管理
12.8. JpaDialect

12.1. 简介

Spring Framework在资源管理,DAO实现支持以及事务策略等方面提供了与 Hibernate、JDO、Oracle TopLink、iBATIS SQL Mappings 以及 JPA 的集成。 以Hibernate为例,Spring通过使用许多IoC的便捷特性对它提供了一流的支持,帮助你处理很多典型的Hibernate整合的问题。 所有用于支持O/R(对象关系)映射的包,都遵循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容器中进行的配置。

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

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

  • 通用数据访问异常封装。 Spring能够封装你所选择的O/R Mapping工具所抛出的异常, 将它们从专有的(潜在的checked)异常转化为一组抽象的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 对象(对于那些建立在Hibernate原生的API上的DAO)。 这样,对于任何的事务环境(本地事务或者JTA),Spring解决了许多在典型Hibernate使用中不断出现的这样那样的问题。

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

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

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

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