对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

DAO支持

Spring中的数据访问对象(DAO)支持旨在以一致的方式方便地使用数据访问技术(如JDBC、Hibernate或JPA)。这使您可以在上述提到的持久化技术之间轻松切换,同时也使您能够在编码时不必担心捕获每种技术特有的异常。spring-doc.cadn.net.cn

一致的异常层次结构

Spring 提供了从特定于技术的异常(例如 SQLException)到其自己的异常类层次结构的便捷转换,其中 DataAccessException 是根异常。这些异常会包装原始异常,因此您永远不会有任何风险而丢失关于可能出错的任何信息。spring-doc.cadn.net.cn

除了JDBC异常之外,Spring还可以包装JPA和Hibernate特有的异常, 将其转换为一组聚焦的运行时异常。这使你可以在适当的层中处理大多数不可恢复的持久化异常,而无需在你的DAO中使用烦人的冗长的catch-and-throw块和异常声明。 (不过你仍然可以在任何需要的地方捕获和处理异常。)如上所述, JDBC异常(包括特定于数据库的方言)也会被转换为相同的层次结构,这意味着你可以在一致的编程模型中执行一些操作。spring-doc.cadn.net.cn

前面的讨论适用于Spring对各种ORM框架的支持中的各种模板类。如果使用基于拦截器的类,应用程序必须自己处理HibernateExceptionsPersistenceExceptions,最好是分别将它们委托给convertHibernateAccessException(..)convertJpaAccessException(..)方法,这些方法将异常转换为与org.springframework.dao异常层次结构中的异常兼容的异常。由于PersistenceExceptions是未检查的异常,它们也可以被抛出(尽管在异常方面牺牲了通用DAO抽象)。spring-doc.cadn.net.cn

以下图像显示了Spring提供的异常层次结构。 (请注意,图像中详细说明的类层次结构仅显示了整个 DataAccessException 层次结构的一个子集。)spring-doc.cadn.net.cn

DataAccessException

用于配置DAO或仓库类的注解

保证你的数据访问对象(DAO)或仓库提供异常转换的最佳方法是使用@Repository注解。此注解还允许组件扫描支持找到并配置你的DAO和仓库,而无需为它们提供XML配置条目。下面的示例展示了如何使用@Repository注解:spring-doc.cadn.net.cn

@Repository (1)
public class SomeMovieFinder implements MovieFinder {
	// ...
}
1 这个 @Repository 注解。
@Repository (1)
class SomeMovieFinder : MovieFinder {
	// ...
}
1 这个 @Repository 注解。

任何DAO或仓库实现都需要访问持久化资源,具体取决于使用的持久化技术。例如,基于JDBC的仓库需要访问JDBC DataSource,而基于JPA的仓库需要访问一个 EntityManager。最简单的方法是通过使用其中一个 @Autowired@Inject@Resource@PersistenceContext 注解来注入此资源依赖。以下示例适用于JPA仓库:spring-doc.cadn.net.cn

@Repository
public class JpaMovieFinder implements MovieFinder {

	@PersistenceContext
	private EntityManager entityManager;

	// ...
}
@Repository
class JpaMovieFinder : MovieFinder {

	@PersistenceContext
	private lateinit var entityManager: EntityManager

	// ...
}

如果您使用经典的 Hibernate API,可以注入 SessionFactory,如下例所示:spring-doc.cadn.net.cn

@Repository
public class HibernateMovieFinder implements MovieFinder {

	private SessionFactory sessionFactory;

	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	// ...
}
@Repository
class HibernateMovieFinder(private val sessionFactory: SessionFactory) : MovieFinder {
	// ...
}

我们在这里展示的最后一个例子是关于典型的JDBC支持。您可以将DataSource注入到初始化方法或构造函数中,在那里您将通过使用这个DataSource来创建一个JdbcTemplate和其他数据访问支持类(例如SimpleJdbcCall和其他类)。下面的例子自动连接了一个DataSourcespring-doc.cadn.net.cn

@Repository
public class JdbcMovieFinder implements MovieFinder {

	private JdbcTemplate jdbcTemplate;

	@Autowired
	public void init(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	// ...
}
@Repository
class JdbcMovieFinder(dataSource: DataSource) : MovieFinder {

	private val jdbcTemplate = JdbcTemplate(dataSource)

	// ...
}
查看每种持久化技术的具体覆盖范围,了解如何配置应用程序上下文以利用这些注解。