Spring ORM 集成简介 (Introduction to ORM with Spring)
Spring Framework 支持与 Java Persistence API (JPA) 的集成,并支持原生 Hibernate 用于资源管理、数据访问对象 (DAO) 实现和事务策略。
对于 Hibernate,Spring 提供了“一等公民”级别的支持,通过一系列便捷的 IoC 特性解决了许多典型的集成问题。你可以通过依赖注入 (DI) 配置所有支持的 OR 映射工具。这些工具可以参与 Spring 的资源和事务管理,并符合 Spring 通用的事务和 DAO 异常体系。
建议
推荐的集成风格是直接针对原生 Hibernate 或 JPA API 编写 DAO 代码,而不是使用过时的 Spring 专用模板类。
使用 Spring ORM 的优势
在构建数据访问应用时,Spring 为你选择的 ORM 层增加了显著的增强:
- 更轻松的测试:Spring 的 IoC 方法使得更换
SessionFactory、DataSource、事务管理器以及映射对象实现变得非常容易。这让你可以轻松地隔离测试每一块持久化相关的代码。 - 通用的数据访问异常:Spring 会包装 ORM 工具抛出的异常,将它们从特定供应商的异常(通常是受检异常)转换为 Spring 通用的
DataAccessException(运行时异常)体系。这让你可以在合适的层级处理不可恢复的持久化异常,而无需编写大量的样板捕获代码。 - 通用的资源管理:Spring 应用上下文可以处理
SessionFactory、EntityManagerFactory或DataSource的位置和配置。这使得这些资源易于管理和更改。Spring 提供了高效、安全、自动化的资源处理(例如,自动将 HibernateSession绑定到当前线程)。 - 集成的事务管理:你可以通过
@Transactional注解或 XML 配置,以声明式的方式包装你的 ORM 代码。事务语义和异常处理(如回滚)都会由 Spring 自动处理。你可以根据需要随时更换事务管理器(例如从本地事务切换到 JTA),而无需修改 ORM 相关代码。
提示
如果你需要更全面的 ORM 支持(包括对 MongoDB 等非关系型数据库的支持),建议查阅 Spring Data 项目。如果你是 JPA 用户,Spring Data JPA 通常是现代项目的首选方案。
补充教学
1. 为什么“原生 API”是推荐的做法?
在 Spring 的早期版本中,开发者通常使用 HibernateTemplate 或 JpaTemplate。 现在为什么不再推荐了? 因为这些模板类会使你的代码与 Spring 框架产生耦合。现代 Spring 允许你直接注入原生的 EntityManager 或 SessionFactory:
@PersistenceContext
private EntityManager entityManager; // 原生 JPA APISpring 会自动在幕后处理这个 EntityManager 的线程安全性和事务关联,让你的代码既简洁又标准。
2. 深入理解 DataAccessException 的价值
当你使用 Hibernate 时,你可能会遇到 HibernateException;当你使用 JPA 时,可能会遇到 PersistenceException。 Spring 把它们统一了。 这意味着如果你决定将底层实现从 Hibernate 切换到另一个 JPA 实现(或者部分改写为 JDBC),你的上层业务代码捕获 DataAccessException 的逻辑不需要修改。这种解耦对于大型项目的架构演进至关重要。
3. 资源管理的“暗箱操作”
在没有 Spring 的情况下,你可能需要手动写这样的代码:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
try {
// 业务逻辑
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
session.close();
}Spring 改变了这一切。通过 @Transactional,Spring 的 TransactionManager 会自动帮你打开 Session,开始事务,并在方法结束时根据成功与否自动提交或回滚,最后关闭 Session。你只需要关注那行“业务逻辑”即可。 No browser pages are currently open. Running terminal commands:
- pnpm run docs:dev (in f:\project\doc, running for 41m30s)