DAO支持
Spring中的数据访问对象(DAO)支持旨在使在数据访问技术(如JDBC、Hibernate或JPA)中以一致的方式工作变得更容易。这使您可以在这些持久性技术之间相对容易地切换,同时也让您编写代码时无需担心捕获特定于每种技术的异常。
一致的异常层次结构
Spring提供了方便的转换,将技术特定的异常(如SQLException
)转换为其自己的异常类层次结构,其中DataAccessException
作为根异常。这些异常包装了原始异常,因此永远不会有任何风险导致您可能会丢失有关可能出错的信息。
除了JDBC异常外,Spring还可以包装JPA和Hibernate特定的异常,将它们转换为一组专注的运行时异常。这使您可以仅在适当的层中处理大多数不可恢复的持久性异常,而无需在DAO中具有烦人的样板式捕获和抛出块以及异常声明。(当然,您仍然可以在需要的任何地方捕获和处理异常。)如上所述,JDBC异常(包括特定于数据库的方言)也转换为相同的层次结构,这意味着您可以在一致的编程模型中执行一些与JDBC相关的操作。
前面的讨论对于Spring对各种ORM框架的支持中的各种模板类也适用。如果您使用基于拦截器的类,应用程序必须关心如何处理HibernateExceptions
和PersistenceExceptions
,最好通过委托给SessionFactoryUtils
的convertHibernateAccessException(..)
或convertJpaAccessException(..)
方法来处理。这些方法将异常转换为与org.springframework.dao
异常层次结构中的异常兼容的异常。由于PersistenceExceptions
是未经检查的,它们也可能被抛出(尽管在异常方面牺牲了通用DAO抽象)。
下面的图片显示了Spring提供的异常层次结构。(请注意,图像中详细显示的类层次结构仅显示了整个DataAccessException
层次结构的一个子集。)
![DataAccessException](https://docs.spring.io/spring-framework/reference/_images/DataAccessException.png)
用于配置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)
// ...
}
有关如何配置应用程序上下文以利用这些注解的具体覆盖范围,请参阅每种持久性技术的详细信息。 |