18. DAO 支持

18.1 简介

Spring 中的 Data Access Object(DAO)支持旨在使您能够以一致的方式轻松使用 JDBC,Hibernate,JPA 或 JDO 等数据访问技术。这允许人们相当容易地在上述持久性技术之间切换,并且还允许人们编码而不必担心捕获特定于每种技术的 exceptions。

18.2 一致的 exception 层次结构

Spring 提供了从 technology-specific exceptions(如SQLException)到其自己的 exception class 层次结构的便捷转换,其中DataAccessException作为根 exception。这些 exceptions 包装了原始的 exception,因此从来没有任何风险可能会丢失任何可能出错的信息。

除了 JDBC exceptions 之外,Spring 还可以包装 Hibernate-specific exceptions,将它们转换为一组专注的运行时 exceptions(JDO 和 JPA exceptions 的 true 相同)。这允许人们只在适当的层中处理大多数持久性 exceptions,它们是 non-recoverable,而不会在一个 DAO 中使用烦人的样板 catch-and-throw 块和 exception 声明。 (人们仍然可以在需要的任何地方捕获和处理 exceptions though.)如上所述,JDBC exceptions(包括 database-specific 方言)也被转换为相同的层次结构,这意味着可以在一致的编程 model 中使用 JDBC 执行某些操作。

以上内容为 Spring 中的各种模板 classes 支持各种 ORM 框架的 true。如果使用 interceptor-based classes 那么 application 必须关心处理HibernateExceptionsJDOExceptions本身,最好是通过委托给SessionFactoryUtils' convertHibernateAccessException(..) or convertJdoAccessException() methods respectively. These methods convert the exceptions to ones that are compatible with the exceptions in the org.springframework.dao exception hierarchy. As JDOExceptions`取消选中,它们也可以简单地抛出,牺牲了 exceptions 方面的泛型 DAO 抽象。 。

Spring 提供的 exception 层次结构如下所示。 (请注意,图中详细说明的 class 层次结构仅显示整个DataAccessException hierarchy.)的子集

DataAccessException

18.3 Annotations 用于配置 DAO 或 Repository classes

保证数据访问 Objects(DAO)或 repositories 提供 exception 转换的最佳方法是使用@Repository annotation。此 annotation 还允许 component 扫描支持查找和配置您的 DAO 和 repositories,而无需为它们提供 XML configuration 条目。

@Repository
public class SomeMovieFinder implements MovieFinder {
    // ...
}

任何 DAO 或 repository implementation 都需要访问持久性资源,具体取决于所使用的持久性技术;对于 example,JDBC-based repository 需要访问 JDBC DataSource; a JPA-based repository 需要访问EntityManager。完成此操作的最简单方法是使用@Autowired,@Inject@Resource@PersistenceContext 注释之一注入此资源依赖项。这是 JPA repository 的 example:

@Repository
public class JpaMovieFinder implements MovieFinder {

    @PersistenceContext
    private EntityManager entityManager;

    // ...

}

如果您使用的是经典的 Hibernate API,那么您可以 inject SessionFactory:

@Repository
public class HibernateMovieFinder implements MovieFinder {

    private SessionFactory sessionFactory;

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

    // ...

}

最后示例我们将在此处显示典型的 JDBC 支持。您可以将DataSource注入到初始化方法中,使用此DataSource创建JdbcTemplate和其他数据访问支持类SimpleJdbcCall等类。

@Repository
public class JdbcMovieFinder implements MovieFinder {

    private JdbcTemplate jdbcTemplate;

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

    // ...

}

有关如何配置 application context 以利用这些注释的详细信息,请参阅每种持久性技术的具体内容。