`
gao_20022002
  • 浏览: 160281 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring整理记录之ORM

阅读更多

Spring Framework在资源管理,DAO实现支持以及事务策略等方面提供了与 Hibernate、JDO、Oracle TopLink、iBATIS SQL Mappings 以及 JPA 的集成。

所有用于支持O/R(对象关系)映射的包,都遵循Spring通用的事务和DAO异常体系。
通常来说有两种不同的整合风格:你可以使用Spring提供的DAO模板,或者直接使用Hibernate/JDO/TopLink等工具的原生API编写DAO。
无论采取哪种风格,这些DAO都可以通过IoC进行配置,并参与到Spring的资源和事务管理中去。

使用Spring Framework构建你的O/R Mapping DAO的好处包括:
便于测试。
通用数据访问异常封装。
通用的资源管理。
完整的事务管理。

在Spring发布包中的PetClinic提供了各种可选择的DAO实现和application context对JDBC、Hibernate、Oracle TopLink和JPA的配置。
JPetStore示例主要举例说明了iBATIS SQL Maps在Spring环境中的使用。

在典型的Spring应用程序中,很多重要的对象都是JavaBeans:数据访问template、数据访问对象(使用template)、事务管理器、业务逻辑对象(使用数据访问对象和事务管理器)、web视图解析器、web控制器(使用业务服务)等等。

为了避免硬编码的资源查找与应用程序对象紧密耦合,Spring允许你在Spring容器中以bean的方式定义诸如JDBC DataSource或者Hibernate SessionFactory 的数据访问资源。
任何需要进行资源访问的应用程序对象只需要持有这些事先定义好的实例的引用。

对于外部对象来说,没有任何实现特定接口的约束,仅仅要求提供一个Hibernate SessionFactory。
 它可以从任何地方得到,不过比较适宜的方法是从Spring的IoC容器中取得bean的引用:通过简单的 setSessionFactory(..) 这个bean的setter方法。

HibernateTemplate类提供了大量方法对应Hibernate Session接口中暴露的方法:快捷函数以及回调实现。

HibernateTemplate 会确保当前Hibernate的 Session 实例的正确打开和关闭,并直接参与到事务管理中去。
Template实例不仅是线程安全的,同时它也是可重用的。因而他们可以作为外部对象的实例变量而被持有。

Spring还提供了一个简便的 HibernateDaoSupport 基类,这个类提供了 setSessionFactory(..) 方法来接受一个 SessionFactory 对象,同时提供了 getSessionFactory() 和 getHibernateTemplate() 方法给子类使用。

不使用回调的基于Spring的DAO实现:
不使用Spring的 HibernateTemplate 来实现DAO的替代解决方案,你依然可以用传统的编程风格来编写你的数据访问代码。
无需将你的Hibernate访问代码包装在一个回调中,只需符合Spring的通用的 DataAccessException 异常体系。
HibernateDaoSupport 基类提供了访问与当前事务绑定的 Session 对象的函数,因而能保证在这种情况下异常的正确转化。
类似的函数同样可以在 SessionFactoryUtils 类中找到,但他们以静态方法的形式出现。
整个调用将在同一个事务内完成(它的整个生命周期由事务控制,避免了关闭返回的 Session 的需要)。
直接使用Hibernate访问代码的好处在于它允许你在数据访问代码中抛出 任何 checked exception,而 HibernateTemplate 却受限于回调中的unchecked exception。

基于Hibernate3的原生API实现DAO:
Hibernate3 引入了一个新的特性:“带上下文环境的Session”。 这一特性使得Hibernate自身具备了每个事务绑定当前 Session 对象的功能。
这与Spring中每个Hibernate的 Session 与事务同步的功能大致相同。
DAO遵循依赖注入模式:它如同使用Spring的 HibernateTemplate 进行编程那样,适合在Spring IoC容器中进行配置。仅仅需要初始化这个类, 调用 setSessionFactory(..) 方法设置你所期望的工厂资源。
这种DAO访问方式的主要优势在于它仅仅依赖于Hibernate API本身而无需引入任何Spring的类。
这样的DAO访问方式会抛出原生 HibernateException (这是一个无需声明或捕获的unchecked exception),
这意味着,DAO的调用者只能以致命的错误来处理这些异常,除非完全依赖Hibernate自身的异常体系。
因而,除非你将DAO的调用者绑定到具体的实现策略上去,否则你将无法捕获特定的异常原因,诸如乐观锁异常。

编程式的事务划分:
我们可以在这些低层次的数据访问服务之上的应用程序进行更高层次的事务划分,从而让事务能够横跨多个操作。
对于相关的业务逻辑对象同样没有实现接口的限制,它只需要一个Spring的 PlatformTransactionManager。
同SessionFactory一样,它可以来自任何地方,但是最好是一个经由 setTransactionManager(..) 方法注入的bean的引用,正如使用 setProductDao 方法来设置 productDAO 一样。

声明式的事务划分:
声明式的事务支持通过配置Spring容器中的AOP Transaction Interceptor来替换事务划分的硬编码。
高级别的声明式的事务管理方案并没有使用 ProxyFactoryBean,它将使那些大量的业务对象需要被纳入到事务管理中时的配置变得非常简单。

事务管理策略
TransactionTemplate 和 TransactionInterceptor 都将真正的事务处理委托给一个 PlatformTransactionManager 实例来处理。
在Hibernate应用中,它可以是一个 HibernateTransactionManager(对于单独一个的Hibernate SessionFactory 使用一个 ThreadLocal 的 Session)
或一个 JtaTransactionManager(代理给容器的JTA子系统)。

对于横跨多个Hibernate SessionFacotry的分布式事务,只需简单地将 JtaTransactionManager 同多个 LocalSessionFactoryBean 的定义结合起来作为事务策略。
你的每一个DAO通过bean属性得到各自的 SessionFactory 引用。
如果所有的底层JDBC数据源都是支持事务的容器,那么只要业务对象使用了 JtaTransactionManager 作为事务策略,它就可以横跨多个DAO和多个session factories来划分事务,而不需要做任何特殊处理。

HibernateTransactionManager 能够自动地将Hibernate事务暴露为JDBC事务,如果你通过设置 DataSource来建立SessionFactory 对象(通过设置 LocalSessionFactoryBean 中的“dataSource”属性)。
另外一种配置方法是通过设置 HibernateTransactionManager 的“dataSource”属性,明确指定事务需要暴露的 DataSource。

容器资源 vs 本地资源:
Spring的资源管理允许你简单地在一个JNDI的 SessionFactory 和一个本地的 SessionFactory 之间切换而无需更改任何一行应用程序代码。
Spring对事务管理的支持有一个非常重要的好处:它不依赖于任何容器。

Spring驱动的事务管理与本地定义的 SessionFactory 能够工作得非常好,就像使用本地的JDBC DataSource 一样,当然前提必须是访问单个数据库。 因此当你真正面对分布式事务的需求时,可以马上回到Spring的JTA事务。

把Hibernate配置成感知到JTA PlatformTransactionManager 实例的存在即可,同时将他们进行同步(与Spring同步)。

Hibernate被配置成不感知JTA PlatformTransactionManager 以及配置成感知JTA PlatformTransactionManager?????
 
JDO:
Spring支持标准的JDO 1.0/2.0 API作为数据访问策略。

Spring提供了一个 LocalPersistenceManagerFactoryBean 类,允许你通过Spring的application context来定义一个本地的JDO PersistenceManagerFactory

iBATIS SQL Maps:
在Spring框架中,iBatis的支持很类似JDBC或者Hibernate的支持。
因为它和JDBC或Hibernate一样支持相同的模板式编程, iBatis的支持能与Spring的异常体系一起工作并让你享用所有Spring的Ioc特点。

事务管理可以由Spring标准机制进行处理。
对于iBATIS来说没有特别的事务策略,除了JDBC Connection 以外,也没有特别的事务资源。
因此,Spring 标准的JDBC DataSourceTransactionManager 或者 JtaTransactionManager 已经能够完全足够了。

使用 SqlMapClientTemplate 和 SqlMapClientDaoSupport:
SqlMapClientDaoSupport 提供了类似 SqlMapDaoSupport 的功能。

基于原生的iBATIS API的DAO实现:
你也可以基于原生的iBATIS API来编程,而无需对Spring产生任何依赖。直接使用注入的 SqlMapClient。


将事务管理纳入到Service操作的执行中,你可以使用Spring通用的声明式的事务管理功能。JPA

作为一个高级特性,JpaTemplate、JpaTransactionManager 和 AbstractEntityManagerFactoryBean 的子类支持用户自定义的 JpaDialect 作为"jpaDialect"的bean属性进行注入。

JpaDialect 实现能够激活一些由Spring支持的高级特性,这通常由特定的 实现供应商指定:
使用特定的事务语义(例如用户自定义的事务隔离级别和事务超时)
获取具备事务功能的Connection对象(暴露给基于JDBC的DAO)
从 PersistenceExceptions 到Spring的 DataAccessExceptions 高级转化。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics