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 提供例外轉換的最佳方法是使用 @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)

	// ...
}
請參閱每種持久性技術的具體涵蓋範圍,以了解如何組態應用程式 Context 以利用這些註解。