持久層是企業應用核心。早期需手寫 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 覆蓋)。
@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 細節映射欄位名、長度、非空等。@Embeddable
public class Address { protected String street1, street2, city, state; ... }
@Entity
public class Employee {
@Embedded
protected Address address;
...
}
@OneToOne、@OneToMany、@ManyToOne、@ManyToManymappedBy 指向擁有端屬性名。| 策略 | 註解 | 特點 |
|---|---|---|
| Single Table (預設) | @Inheritance(strategy=SINGLE_TABLE) + @DiscriminatorColumn | 單表儲存全階層,需鑑別欄 |
| Joined Subclass | @Inheritance(strategy=JOINED) | 父表儲存共同欄位,子表儲存特有欄位 |
| Table per Class | @Inheritance(strategy=TABLE_PER_CLASS) | 各類別獨立表,**不建議**使用 |
@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;
...
}
| 方法 | 用途 |
|---|---|
persist(entity) | 持久化新實體 |
merge(entity) | 合併遊離實體 |
remove(entity) | 刪除實體 |
find(Class, pk) | 依主鍵查詢 |
flush() | 同步快取至資料庫 |