Jakarta Persistence 定義了用於物件關聯映射的標準 Java API。Hibernate 是廣泛使用的實作。Spring Data JPA 在 Jakarta Persistence 提供者之上建立儲存庫抽象層。
Jakarta Persistence 模型 #
應用程式使用 @Entity、@Table、@Id 和 @Column 等註解,將一般類別映射至資料庫資料表:
@Entity
@Table(name = "orders")
public class PurchaseOrder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String status;
}標準 API 位於 jakarta.persistence。實作會透過 Java 的服務提供者機制探索 jakarta.persistence.spi.PersistenceProvider。提供者會將持久化操作,以及 JPQL 或 Criteria 查詢,轉換為資料庫特定的 SQL。
在獨立應用程式中,請在 META-INF/persistence.xml 中定義持久化單元,建立 EntityManagerFactory,並在應用程式停止時將其關閉:
EntityManagerFactory emf =
Persistence.createEntityManagerFactory("application");
try {
EntityManager em = emf.createEntityManager();
// 在變更操作外圍開始並提交交易
em.close();
} finally {
emf.close();
}持久化單元提供提供者、受管理的實體類別、資料來源或 JDBC 設定,以及提供者屬性。請優先使用容器管理的資料來源和外部化認證資訊,而不是將資料庫密碼嵌入 persistence.xml。
實體管理器、交易與查詢 #
EntityManager 代表一個持久化內容:在該內容中,一個受管理 Java 物件的識別對應至一個資料庫識別。請在適當的交易中持久化、合併、移除及查詢實體。EntityManagerFactory 建立成本高且具有應用程式範圍;EntityManager 通常具有要求範圍或交易範圍,而且不是執行緒安全的。
JPQL 查詢的是實體名稱和屬性,而不是資料表和欄:
List<PurchaseOrder> orders = em.createQuery(
"select o from PurchaseOrder o where o.status = :status",
PurchaseOrder.class)
.setParameter("status", "PAID")
.getResultList();請使用具名參數,而不要將輸入串接至 JPQL。Criteria API 為動態查詢提供程式化替代方案。
Hibernate #
Hibernate 實作 Jakarta Persistence,也公開選用的原生功能。請先使用標準 API,以維持可攜性。只有在 Hibernate 擴充功能的價值明確時才使用,並記錄因此產生的廠商相依性。
延遲關聯會將擷取延後到存取關聯時。這可以避免不必要的工作,但在持久化內容之外可能造成 LazyInitializationException,在持久化內容內可能造成 N+1 查詢問題。請使用 fetch join、實體圖、批次處理或投影,明確設計擷取計畫;不要透過將所有關聯設為 eager 來解決每個問題。
結構描述產生功能便於本機開發,但正式環境的結構描述變更應經過審查,並透過遷移工具套用。
Spring Data JPA 儲存庫 #
Spring Data 可以為擴充 Repository(通常是 JpaRepository)的介面產生儲存庫實作:
public interface PurchaseOrderRepository
extends JpaRepository<PurchaseOrder, Long> {
List<PurchaseOrder> findByStatus(String status);
}Spring 會透過設定或 Boot 自動設定探索儲存庫,並以 Bean 管理其生命週期。JpaRepository 提供 CRUD、分頁和排序方法。衍生查詢名稱適合簡單述詞;如果方法名稱會變得不清楚,請使用 @Query、Specifications 或自訂儲存庫。
涉及多個儲存庫或外部作用的業務操作,應將交易邊界放在服務層。唯讀交易可以傳達意圖並允許提供者進行最佳化,但不是安全機制。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)