DAO 支持

Spring中的数据访问对象 (DAO) 支持旨在简化以一致的方式使用数据访问技术(例如JDBC、Hibernate或JPA)的工作。这使您可以相当轻松地在上述持久性技术之间切换,并且还可以让您在编码时不必担心捕获特定于每种技术的异常。

一致的异常层次结构

Spring提供了一种方便的技术特定异常(例如SQLException)到其自身异常类层次结构的转换,该层次结构以DataAccessException作为根异常。这些异常会包装原始异常,因此您永远不会冒丢失任何有关可能出错的信息的风险。

除了JDBC异常外,Spring还可以包装JPA和Hibernate特定的异常,并将它们转换为一组集中的运行时异常。这使您可以仅在适当的层中处理大多数不可恢复的持久性异常,而无需在您的DAO中使用烦人的样板捕获和抛出块以及异常声明。(但是您仍然可以在需要的地方捕获和处理异常。)如上所述,JDBC异常(包括特定于数据库的方言)也会转换为相同的层次结构,这意味着您可以使用JDBC在一致的编程模型中执行某些操作。

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

下图显示了Spring提供的异常层次结构。(请注意,图像中详细介绍的类层次结构仅显示了整个DataAccessException层次结构的子集。)

DataAccessException

用于配置DAO或Repository类的注解

确保您的数据访问对象 (DAO) 或存储库提供异常转换的最佳方法是使用@Repository注解。此注解还允许组件扫描支持查找和配置您的DAO和存储库,而无需为它们提供XML配置条目。以下示例显示了如何使用@Repository注解

  • Java

  • Kotlin

@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存储库

  • Java

  • Kotlin

@Repository
public class JpaMovieFinder implements MovieFinder {

	@PersistenceContext
	private EntityManager entityManager;

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

	@PersistenceContext
	private lateinit var entityManager: EntityManager

	// ...
}

如果您使用经典的Hibernate API,您可以注入SessionFactory,如下例所示

  • Java

  • Kotlin

@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等)。以下示例自动装配DataSource

  • Java

  • Kotlin

@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)

	// ...
}
有关如何配置应用程序上下文以利用这些注解的详细信息,请参阅每种持久性技术的具体介绍。