首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

EJB 3 Java Persistence API (JPA) 完整指南:標準化 ORM、實體映射與 JPQL 查詢

     編輯:Java 相關知識

背景:為何需要 JPA?

持久層是企業應用核心。早期需手寫 JDBC/SQL,後出現 TopLink、Hibernate、Kodo 等 ORM 框架簡化開發。EJB 2.x CMP 嘗試標準化但採用複雜。EJB 3 JPA (JSR-220) 終於提供 **Java EE/SE 通用的標準持久化 API**,獲主流廠商廣泛支援。

領域模型範例

Department 1 —< * Employee,FullTime、Contractor 繼承 Employee (雙向關聯)。

一、啟用中繼資料註解

Java SE 5.0 引入 Annotation,JPA 大量使用簡化配置(亦可用 XML 覆蓋)。

二、標準化 O-R 映射

1. 定義實體

@Entity
@NamedQuery(name="findAllDepartment", query="select o from Department o")
@Table(name="DEPT")
public class Department implements Serializable {
    @Id @Column(nullable=false)
    protected Long deptNo;

    @Column(name="DNAME")
    protected String name;

    @Column(name="LOC")
    protected String location;

    @OneToMany(mappedBy="department")
    protected Collection<Employee> employees;

    // getter/setter、add/removeEmployee 方法...
}
  • @Entity 標記 POJO 為實體。
  • @Id 標記主鍵 (欄位或屬性存取二擇一,全類別需一致)。
  • @Table 指定資料表名,預設同類別名。
  • @Column 細節映射欄位名、長度、非空等。

2. 可嵌入物件

@Embeddable
public class Address { protected String street1, street2, city, state; ... }

@Entity
public class Employee {
    @Embedded
    protected Address address;
    ...
}

3. 關聯映射

  • @OneToOne、@OneToMany、@ManyToOne、@ManyToMany
  • 雙向關聯需在 **非擁有端** 使用 mappedBy 指向擁有端屬性名。

4. 繼承策略

策略註解特點
Single Table (預設)@Inheritance(strategy=SINGLE_TABLE) + @DiscriminatorColumn單表儲存全階層,需鑑別欄
Joined Subclass@Inheritance(strategy=JOINED)父表儲存共同欄位,子表儲存特有欄位
Table per Class@Inheritance(strategy=TABLE_PER_CLASS)各類別獨立表,**不建議**使用

範例:Single Table 策略

@Entity @Table(name="EMP")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="EMPLOYEE_TYPE", discriminatorType=DiscriminatorType.STRING, length=1)
public abstract class Employee implements Serializable { ... }

@Entity @DiscriminatorValue("F")
public class FullTime extends Employee {
    @Column(name="SAL") protected Double salary;
    @Column(name="COMM") protected Double commission;
    ...
}

@Entity @DiscriminatorValue("C")
public class Contractor extends Employee {
    @Column(name="RATE") protected Double hourlyRate;
    ...
}

三、EntityManager API:標準 CRUD 操作

取得 EntityManager

  • **Container-managed** (Java EE): @PersistenceContext(unitName="onjava") private EntityManager em;
  • **Application-managed** (Java SE/獨立): @PersistenceUnit EntityManagerFactory emf; EntityManager em = emf.createEntityManager(); 用畢 em.close()。

交易邊界

所有資料庫變更操作必須在交易內執行 (JTA 或 Resource Local)。

四、Java Persistence Query Language (JPQL)

JPQL 擴展 EJB-QL 2.x,支援:

  • 簡化查詢語法
  • JOIN 操作 (INNER JOIN, LEFT JOIN)
  • GROUP BY / HAVING
  • 子查詢
  • 動態查詢與命名查詢
  • 命名參數 (:param)
  • 批次更新/刪除 (UPDATE ... SET ... WHERE, DELETE ... WHERE)

動態查詢

Query q = em.createQuery("select e from Employee e where e.empNo > :no");
q.setParameter("no", 100);
return q.getResultList();

命名查詢 (於實體定義)

@Entity
@NamedQuery(name="findAllEmployee", query="select e from Employee e where e.empNo > :no")
public abstract class Employee { ... }
Query q = em.createNamedQuery("findAllEmployee");
q.setParameter("no", 100);
return q.getResultList();

五、打包與部署

實體可打包於 Web 模組、EJB-JAR、EAR 函式庫或獨立 JAR。需在 META-INF 下放置 persistence.xml:

<persistence>
  <persistence-unit name="onjava">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <jta-data-source>jdbc/OracleDS</jta-data-source>
    <!-- 類別自動發現,無需列出 -->
  </persistence-unit>
</persistence>

六、參考實作與工具

  • 參考實作:EclipseLink (GlassFish)、OpenJPA (Apache)、Hibernate EntityManager。
  • 開發工具:Eclipse Dali、Oracle JDeveloper 10.1.3+、BEA Workshop Studio。

結語

JPA 以 Annotation 為核心、預設大於配置、標準化 API 統一了 Java 持久化開發體驗。隨 Java EE 5 正式釋出,主流應用伺服器皆將內建支援,是建構企業級持久層的首選標準。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法用途
persist(entity)持久化新實體
merge(entity)合併遊離實體
remove(entity)刪除實體
find(Class, pk)依主鍵查詢
flush()同步快取至資料庫