第15章 Spring对各种ORM的集成
15.3 Spring中对其他ORM方案的集成概述
不管是从对各种ORM产品的 集成理论以及集成方式 上看,还是从对各种ORM产品 集成关注点来看,Spring对各种ORM产品的集成几乎是一脉相承的。
所以,对于Spring中其他几种ORM产品的集成情况,没有必要再重复几乎一样的理论和方式,因此以下内容仅作提点,不着更多笔墨。
回顾Spring对各种数据访问技术的集成,我们可以归纳出如下几点。
1. 集成理论和方式上
各种数据访问方式的管理和使用通过相应的模板方法类来统一建模,而具体的数据访问逻辑则统一由相应的回调接口提供,从而将数据访问资源的管理和具体的数据访问逻辑相分离 。
2. 集成关注点上
Spring对各种数据访问技术的集成主要集中在以下三个关注点上。
-
数据访问资源管理 ,主要涉及两种管理对象,如下所述。
- 连接工厂(ConnectionFactory)。 连接工厂代表的是创建数据访问会话资源的统一概念 ,通常可以通过特定的数据访问技术的支持来直接创建它们,也可以通过JNDI等服务获取已经创建并配置好的实例。对于JDBC来说,对应连接工厂概念的实体是DataSource,Hibernate是SessionFactory,iBATIS是SqlMapClient……
- 连接(Connection)或者说会话资源。 连接是客户端与数据媒介进行数据通信的纽带 ,每次进行数据访问的时候,都需要从指定的连接工厂获得某个连接以完成本次数据访问操作,操作完成后关闭当前连接资源。对于JDBC来说,连接概念对应的是java.sql.Connection,对于Hibernate来说,对应的是Session,对于iBATIS是SqlMapSession…
通常,Spring通过FactoryBean对相应的连接工厂资源的配置和创建进行封装,使得它们能够很好地集成到IoC容器中。对于连接资源的管理,则是由相应的模板方法类来处理。
-
特定数据访问 异常的转译 ,将这些特定的数据访问异常转译为Spring统一的数据访问异常体系,从而使得客户端可以使用统一的方式透明的处理数据访问异常。
-
将特定于数据访问技术的 事务管理 ,统一纳入到Spring的事务管理抽象层,使得我们可以用统一的方式来管理事务。最主要的是,通过Spring的事务管理抽象层,我们可以得到EJB2时代只有通过相应的EJBContainer才能获得的声明式事务支持。事务管理是一个大的话题,此处只介绍最初的两个关注点。在此基础上,让我们来快速浏览一遍Spring支持的其他数据访问技术。
15.3.1 Spring对JDO的集成
JDO(Java Data Object,网址为http://java.sun.com/jdo/)是Sun提出来的数据持久化规范。该规范从1.0版本发展到现在的2.0版本,虽然整个发展历程不如Hibernae那样突飞猛进,但也涌现了不少优秀的JDO产品实现,比如KodoJDO、JPOX(http://www.jpox.org/)等。现在JDO规范的发展主要由ApacheJDO(http://db.apache.org/jdo/index.html)开源项目来推动。
更多不做介绍 有兴趣可以看原文
15.3.2 Spring对TopLink的集成
TopLink的命运比较曲折,作为最初由Object People公司开发的几乎是Java界ORM产品鼻祖的Toplink,在20世纪90年代末被短命的WebGain收购之后,没过多久又被Oracle收购,并一直跟随Oracle走到今天,然后在2007年被Oracle开源。但不管怎么说,作为一个商业产品,Toplink还是值得世人称道的。
更多不做介绍 有兴趣可以看原文
15.3.3 Spring对JPA的集成
JPA(Java Persistence API,Java持久化API)是Sun于Java EE 5之后提出的ORM解决方案的统一标准,具体实现由不同提供商提供,包括Hibernate、Toplink等。就好像当年的JDBC标准一样,只不过,JPA是面向ORM的统一。
Spring框架在2.0版本之后提供了对JPA的支持,并且在之后的版本中做进一步的统一和完善。
1. Spring中JPA的资源管理
JPA中的EntityManagerFactory对应数据访问的ConnectionFactory的概念,Spring提供了如下三种方式来配置和获取EntityManagerFactory。
使用LocalEntityManagerFactoryBean。
对于基于JavaSE的独立应用程序或者测试环境下的开发,我们可以使用org.springframework.orm.jpa.LocalEntityManagerFactoryBean
来获取相应的EntityManagerFactory。
LocalEntityManagerFactoryBean将默认读取META-INF/persistence.xml
配置文件信息,来构建相应的EntityManagerFactory,我们只需要指定相应的persistenceUnitName即可,如下所示:
这种方式应用场景有限,对于更多定制需求,可以考虑使用LocalContainerEntityManagerFactoryBean。
使用LocalContainerEntityManagerFactoryBean。org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
是比较常用的配置和获取EntityManagerFactory的方式。通过它,我们可以指定自定义的配置文件位置、独立的dataSource定义甚至Spring提供的定制字节码转换的loadTimeWeaver实现。
下方代码清单给出了Spring IoC容器内LocalContainerEntityManagerFactoryBean通常的配置代码示例。
通过JNDI获取EntityManagerFactory。 我们也可以使用绑定到JNDI的EntityManagerFactory,这对基于Spring的IOC容器的应用来说,也只是配置文件的少许改动,例如:
当然,Spring2.0之后,我们更喜欢用XSD风格的配置,如下所示
相对来说,这种方式更加简洁,描述性也更强。
获取EntityManagerFactory实例之后,我们就可以使用Spring为JPA提供的模板方法类org.springframework.orm.jpa.JpaTemplate
进行数据访问了。
JpaTemplate的核心模板方法为Object execute(JpaCallback action)
,开发人员直接通过org.springframework.orm.jpa.JpaCallback
回调接口提供具体的数据访问逻辑即可。资源管理、事务以及异常处理等关注点,则由JpaTemplate模板方法来统一管理。
JpaCallback接口定义为开发人员公开了EntityManager实例,用于具体的基于JPA的数据访问操作,该接口定义如下:
通过EntityManager,开发人员可以完成任何基于JPA原始API可以完成的工作,而EntityManager获取以及释放的管理问题,则由JpaTemplate来处理。
org.springframework.orm.jpa.JpaOperations
接口定义了所有JpaTemplate中可用的数据访问模板方法,除了核心的execute(JpaCallback)
模板方法,还有一些便于常用操作的模板方法,具体可以参阅JpaOperations或者JpaTemplate的Javadoc文档。
注意更多有关JpaTemplate使用以及EntityManagerFactory实例配置和获取的信息,请参照Spring2.0之后提供的参考文档。
2. Spring中JPA的异常转译
JpaTemplate模板方法内部同时处理了JPA的数据访问异常到Spring统一异常体系的转译。如果使用JpaTemplate进行数据访问,那么不用关心对于特定于JPA的数据访问异常的处理。即使我们在自己的DAO实现中没有使用JpaTemplate,而是使用JPA的原始API进行数据访问,依然能够得到Spring统一异常体系的好处。
实际上,JpaTemplate内部的异常转译最终是通过org.springframework.orm.jpa.EntityManagerFactoryUtils
提供的静态方法convertJpaAccessExceptionIfPossible()
完成的,该方法签名定义如下:
如果需要,我们同样可以直接使用该工具类提供的这个方法来完成到Spring统一异常体系的转译。
3. JpaDaoSupport
Spring为所有基于JPA进行数据访问的DAO实现类提供了一个统一的基类,即org.springframework.orm.jpa.support.JpaDaoSupport
,相应的DAO实现类可以直接继承JpaDaoSupport,以获得JpaTemplate提供的JPA数据访问支持。
当然,JpaDaoSupport允许我们注入EntityManagerFactory或者EntityManager实例。如果愿意,我们也可以直接使用JPA的原始API进行数据访问。
注意:本章的主要内容是Spring通过什么理念和操作方式对各种数据访问进行集成,所以,并没有对各种数据访问技术进行详尽的介绍。实际上,要发挥各种数据访问技术的最大功效,我们依然需要精通使用的数据访问技术才行,而这与集成没有太多关系的。集成只是让事情变得更简单。
15.4 小结
Spring框架为当下Java平台上的各种ORM解决方案提供了统一的集成支持,包括数据访问资源的模板化管理、特定的数据访问异常到Spring异常层次体系的转译,以及稍后将会提到的Spring事务管理支持等。
本章主要针对Hibernate和iBATIS两种目前比较流行的ORM解决方案的Spring集成进行了比较详尽的介绍。鉴于Spring对各种ORM产品的集成一脉相承,对其他ORM产品的集成则顺带提及。在阅读完本章内容后,你应该已经对生活在Spring数据访问层的各种ORM产品的使用了如指掌了。