通用 ORM 集成考虑因素
本节重点介绍了适用于所有ORM技术的考虑因素。Hibernate部分提供了更多详细信息,并在具体场景中展示了这些特性和配置。
Spring的ORM集成的主要目标是实现清晰的应用层结构(无论使用何种数据访问和事务技术),以及降低应用对象之间的耦合度——不再有业务服务对数据访问或事务策略的依赖,不再需要硬编码的资源查找,不再需要难以替换的单例对象,也不再需要自定义的服务注册器。其目标是提供一种简单一致的方式来连接应用对象,尽可能使这些对象可重用,并减少对容器的依赖。所有的单独数据访问功能都可以独立使用,但也能与Spring的应用上下文概念很好地集成,提供基于XML的配置方式,并能够实现普通JavaBean实例之间的交叉引用,而这些JavaBean实例不必具备对Spring的感知能力。在典型的Spring应用程序中,许多重要的对象都是JavaBean:数据访问模板、数据访问对象、事务管理器、使用数据访问对象和事务管理器的业务服务、Web视图解析器、使用业务服务的Web控制器等等。
资源与事务管理
典型的业务应用程序中充斥着重复的资源管理代码。许多项目试图发明自己的解决方案,有时为了编程便利而牺牲了对错误的正确处理。Spring提倡简单的资源处理方案,即在JDBC的情况下通过模板实现依赖注入(IoC),对于对象关系映射(ORM)技术则应用面向切面编程(AOP)拦截器。
在事务管理方面,JdbcTemplate类与Spring的事务支持机制相结合,通过相应的Spring事务管理器支持JTA和JDBC事务。对于所支持的ORM技术,Spring通过Hibernate和JPA事务管理器提供对Hibernate和JPA的支持,同时也支持JTA。有关事务管理的详细信息,请参阅事务管理章节。
异常翻译
当你在DAO中使用Hibernate或JPA时,你必须决定如何处理持久化技术的原生异常类。根据所使用的技术不同,DAO会抛出HibernateException或PersistenceException的子类。这些异常都属于运行时异常,不需要进行声明或捕捉。你可能还需要处理IllegalArgumentException和IllegalStateException。这意味着调用者只能将这些异常视为通常会导致程序终止的错误,除非他们愿意依赖持久化技术自身的异常结构。如果不将调用者与实现策略绑定起来,就无法捕捉到特定的异常原因(例如乐观锁失败)。对于那些主要基于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自定义的异常层次结构。