20220507 2. Data Access - DAO Support

前言

文档地址

Spring 中的数据访问对象 (Data Access Object,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 层次结构的一个子集 )

数据访问异常

参考源码

  • org.springframework.orm.hibernate5.SessionFactoryUtils#convertHibernateAccessException
  • SessionFactoryUtils 中没有 convertJpaAccessException 方法
  • org.springframework.dao.DataAccessException

用于配置 DAO 或存储库(Repository) 类的注解

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

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

任何 DAO 或存储库实现都需要访问持久层资源,具体取决于所使用的持久层技术。例如,基于 JDBC 的存储库需要访问 JDBC DataSource ,而基于 JPA 的存储库需要访问 EntityManager 。实现这一点的最简单方法是使用 @Autowired@Inject@Resource@PersistenceContext 注解之一注入此资源依赖关系。以下示例适用于 JPA 存储库:

@Repository
public class JpaMovieFinder implements MovieFinder {

    @PersistenceContext
    private EntityManager entityManager;

    // ...
}

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

@Repository
public class HibernateMovieFinder implements MovieFinder {

    private SessionFactory sessionFactory;

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

    // ...
}

至于 JDBC 支持,您可以将 DataSource 注入到初始化方法或构造函数中,您可以使用 DataSource 创建 JdbcTemplate 和其他数据访问支持类(例如 SimpleJdbcCall )。以下示例自动装配 DataSource

@Repository
public class JdbcMovieFinder implements MovieFinder {

    private JdbcTemplate jdbcTemplate;

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

    // ...
}
posted @ 2022-06-09 21:19  流星<。)#)))≦  阅读(42)  评论(0编辑  收藏  举报