DAO 支援
Spring 的 Data Access Object (DAO) 支援旨在提供一種一致的方式,使處理資料訪問技術(如 JDBC、Hibernate 或 JPA)變得容易。這使你可以相當輕鬆地在上述持久化技術之間切換,並且無需擔心捕獲特定於每種技術的異常即可編寫程式碼。
一致的異常層次結構
Spring 提供了一種便捷的轉換,將技術特定的異常(如 SQLException
)轉換為它自己的異常類層次結構,該層次結構的根異常是 DataAccessException
。這些異常會包裝原始異常,因此你絕不會有丟失有關發生錯誤的資訊的風險。
除了 JDBC 異常外,Spring 還可以包裝 JPA 和 Hibernate 特定的異常,將它們轉換為一組集中的執行時異常。這使得你可以在適當的層中處理大多數不可恢復的持久化異常,而無需在你的 DAO 中編寫煩人的樣板 catch-and-throw 程式碼塊和異常宣告。(當然,你仍然可以在需要的地方捕獲和處理異常。)如上所述,JDBC 異常(包括資料庫特定的方言)也會被轉換到相同的層次結構中,這意味著你可以在一致的程式設計模型中執行一些 JDBC 操作。
前面的討論對於 Spring 支援各種 ORM 框架中的各種模板類同樣適用。如果你使用基於攔截器的類,應用程式本身必須處理 HibernateExceptions
和 PersistenceExceptions
,最好分別委託給 SessionFactoryUtils
的 convertHibernateAccessException(..)
或 convertJpaAccessException(..)
方法。這些方法將異常轉換為與 org.springframework.dao
異常層次結構中的異常相容的異常。由於 PersistenceExceptions
是 unchecked 異常,它們也可以被丟擲(儘管犧牲了異常層面的通用 DAO 抽象)。
下圖展示了 Spring 提供的異常層次結構。(請注意,圖片中詳細的類層次結構僅顯示了整個 DataAccessException
層次結構的一部分。)

用於配置 DAO 或 Repository 類的註解
確保你的 Data Access Objects (DAO) 或 repository 提供異常轉換的最佳方法是使用 `@Repository` 註解。這個註解還允許元件掃描支援找到並配置你的 DAO 和 repository,而無需為其提供 XML 配置條目。以下示例展示瞭如何使用 `@Repository` 註解
-
Java
-
Kotlin
@Repository (1)
public class SomeMovieFinder implements MovieFinder {
// ...
}
1 | `@Repository` 註解。 |
@Repository (1)
class SomeMovieFinder : MovieFinder {
// ...
}
1 | `@Repository` 註解。 |
任何 DAO 或 repository 實現都需要訪問持久化資源,這取決於所使用的持久化技術。例如,基於 JDBC 的 repository 需要訪問 JDBC DataSource
,而基於 JPA 的 repository 需要訪問 EntityManager
。最簡單的方法是使用 `@Autowired`、`@Inject`、`@Resource` 或 `@PersistenceContext` 註解中的一個來注入這個資源依賴。以下示例適用於 JPA repository
-
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)
// ...
}
有關如何配置應用程式上下文以利用這些註解的詳細資訊,請參閱每種持久化技術的具體介紹。 |