|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
通用 ORM 集成注意事项
本节重点介绍适用于所有ORM技术的注意事项。 Hibernate部分提供了更多详细信息,并在具体上下文中展示了这些特性和配置。
Spring ORM 集成的主要目标是实现清晰的应用分层(适用于任何数据访问和事务技术),并使应用程序对象之间保持松耦合——不再让业务服务依赖于特定的数据访问或事务策略,不再使用硬编码的资源查找,不再使用难以替换的单例,也不再需要自定义的服务注册表。目标是采用一种简单且一致的方式来装配应用程序对象,使其尽可能可重用,并尽量减少对容器的依赖。所有独立的数据访问功能均可单独使用,但也能很好地与 Spring 的应用上下文(application context)概念集成,提供基于 XML 的配置,并支持对普通的 JavaBean 实例进行交叉引用,而这些 JavaBean 实例无需感知 Spring 的存在。在典型的 Spring 应用程序中,许多重要的对象都是 JavaBean:数据访问模板、数据访问对象、事务管理器、使用数据访问对象和事务管理器的业务服务、Web 视图解析器、使用业务服务的 Web 控制器,等等。
资源和事务管理
典型的企业应用程序充斥着重复的资源管理代码。 许多项目试图自行设计解决方案,有时为了编程上的便利而牺牲了对故障的正确处理。 Spring 提倡采用简单的方案来实现恰当的资源处理,具体而言,对于 JDBC 使用基于模板的 IoC 方式,而对于 ORM 技术则应用 AOP 拦截器。
该基础设施提供了恰当的资源处理机制,并将特定 API 异常正确地转换为一套非受检(unchecked)的基础设施异常层次结构。Spring 引入了一个 DAO 异常层次结构,适用于任何数据访问策略。对于直接使用 JDBC 的情况,前一节中提到的 ../jdbc/core.html#jdbc-JdbcTemplate 类提供了连接管理,并将 SQLException 正确地转换为 DataAccessException 异常层次结构,包括将数据库特定的 SQL 错误代码翻译为具有明确含义的异常类。关于 ORM 技术,请参阅下一节,了解如何获得相同的异常转换优势。
在事务管理方面,JdbcTemplate 类会集成 Spring 的事务支持,并通过相应的 Spring 事务管理器同时支持 JTA 和 JDBC 事务。对于所支持的 ORM 技术,Spring 还通过 Hibernate 和 JPA 事务管理器提供对 Hibernate 和 JPA 的支持,同时也支持 JTA。有关事务支持的详细信息,请参阅事务管理章节。
异常转换
当你在 DAO 中使用 Hibernate 或 JPA 时,必须决定如何处理持久化技术的原生异常类。DAO 抛出 HibernateException 或 PersistenceException 的子类,具体取决于所使用的技术。这些异常都是运行时异常,无需声明或捕获。您还可能需要处理
IllegalArgumentException 和 IllegalStateException。这意味着调用者只能将异常视为通常是致命的,除非他们希望依赖于持久化技术自身的异常结构。在不将调用方与实现策略绑定的情况下,无法捕获特定原因(例如乐观锁失败)。这种权衡对于那些高度基于 ORM 的应用程序,或者不需要任何特殊异常处理(或两者兼有)的应用程序来说,可能是可以接受的。然而,Spring 通过 @ControllerAdvice 注解透明地应用异常处理。以下示例(一个使用 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 自定义的异常层次结构。