通用 ORM 集成考量

本节重点介绍适用于所有 ORM 技术的考量因素。Hibernate 一节提供了更多详细信息,并展示了这些特性和配置的具体上下文。

Spring ORM 集成的主要目标是清晰的应用分层(适用于任何数据访问和事务技术),以及应用对象的松耦合——不再需要业务服务依赖于数据访问或事务策略,不再需要硬编码的资源查找,不再需要难以替换的单例,不再需要自定义服务注册表。目标是采用一种简单且一致的方法来连接应用对象,使其尽可能地可重用并独立于容器依赖。所有独立的数据访问特性都可以单独使用,但也与 Spring 的应用上下文概念很好地集成,提供基于 XML 的配置和对无需 Spring 感知的普通 JavaBean 实例的交叉引用。在典型的 Spring 应用中,许多重要的对象都是 JavaBean:数据访问模板、数据访问对象、事务管理器、使用数据访问对象和事务管理器的业务服务、web 视图解析器、使用业务服务的 web 控制器等等。

资源和事务管理

典型的业务应用中充斥着重复的资源管理代码。许多项目试图发明自己的解决方案,有时为了编程便利而牺牲了对故障的正确处理。Spring 提倡采用简单的解决方案来正确处理资源,即在 JDBC 的情况下通过模板使用 IoC,以及对 ORM 技术应用 AOP 拦截器。

基础设施提供适当的资源处理,并将特定的 API 异常适当转换为非受检的基础设施异常层次结构。Spring 引入了 DAO 异常层次结构,适用于任何数据访问策略。对于直接 JDBC,前一节中提到的 JdbcTemplate 类接入 Spring 事务支持,通过各自的 Spring 事务管理器支持 JTA 和 JDBC 事务。对于支持的 ORM 技术,Spring 通过 Hibernate 和 JPA 事务管理器以及 JTA 支持提供 Hibernate 和 JPA 支持。有关事务支持的详细信息,请参阅事务管理一章。

When it comes to transaction management, the JdbcTemplate class hooks in to the Spring transaction support and supports both JTA and JDBC transactions, through respective Spring transaction managers. For the supported ORM technologies, Spring offers Hibernate and JPA support through the Hibernate and JPA transaction managers as well as JTA support. For details on transaction support, see the Transaction Management chapter.

异常转换

在 DAO 中使用 Hibernate 或 JPA 时,必须决定如何处理持久化技术的原生异常类。DAO 会根据使用的技术抛出 HibernateExceptionPersistenceException 的子类。这些异常都是运行时异常,无需声明或捕获。您可能还需要处理 IllegalArgumentExceptionIllegalStateException。这意味着调用者只能将异常视为通常是致命的,除非他们想依赖于持久化技术自身的异常结构。在不将调用者绑定到实现策略的情况下,无法捕获特定的原因(例如乐观锁失败)。对于高度依赖 ORM 的应用或不需要任何特殊异常处理的应用(或两者兼有),这种权衡可能是可以接受的。但是,Spring 允许通过 @Repository 注解透明地应用异常转换。以下示例(一个用于 Java 配置,一个用于 XML 配置)展示了如何实现:

  • Java

  • Kotlin

@Repository
public class ProductDaoImpl implements ProductDao {

	// class body here...

}
@Repository
class ProductDaoImpl : ProductDao {

	// class body here...

}
<beans>

	<!-- Exception translation bean post processor -->
	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

	<bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

后处理器会自动查找所有异常转换器(PersistenceExceptionTranslator 接口的实现),并通知所有标有 @Repository 注解的 Bean,以便发现的转换器可以拦截抛出的异常并应用适当的转换。

总而言之,您可以基于原生的持久化技术 API 和注解来实现 DAO,同时仍然受益于 Spring 管理的事务、依赖注入以及(如果需要)对 Spring 自定义异常层次结构的透明异常转换。