近年來,ORM(Object-Relational Mapping,物件關聯映射)技術市場蓬勃發展,各類持久化框架層出不窮,其中 Hibernate 和 TopLink 影響力最大。Sun 公司吸收現有優秀 ORM 框架(特別是 Hibernate)的設計精華,制定了 JPA(Java Persistence API)規範,為當時混亂的持久化市場帶來統一標準。JPA 規範小組領導人正是 Hibernate 創始人 Gavin King,因此 JPA 大量參考了 Hibernate 的設計,熟悉 Hibernate 的開發者上手 JPA 將非常容易,且得益於 JDK 5.0 引入的註解特性,使用起來更加簡潔直觀。
首先看一個簡單範例,展示如何將單一 Java 類映射到資料庫表:
@Entity
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
private String name;
private int age;
private String address;
// Getters and Setters
}
若無 @Entity 和 @Id 註解,這只是一個典型的 POJO。加上這兩個註解後,它即成為可對應資料庫表的實體類。預設映射規則為:表名與類名相同,欄位名與屬性名相同。
@javax.persistence.Entity 註解@javax.persistence.Id 標註主鍵java.io.SerializableJPA 採用「Configuration by Exception」理念:容器提供預設規則,開發者僅在有特殊需求時覆寫。使用 @Table 和 @Column 即可修改預設映射:
@Entity
@Table(name="Workers")
public class Employee implements Serializable {
@Id @GeneratedValue
private Long id;
@Column(name="emp_name", length=30)
private String name;
@Column(name="emp_age", nullable=false)
private int age;
@Column(name="emp_address", nullable=false, unique=true)
private String address;
// Getters and Setters
}
類層級註解,屬性包含:
name:資料庫表名,預設為類名catalog、schema:目錄與綱要uniqueConstraints:唯一約束可用於方法或欄位前,主要屬性:
name:欄位名unique、nullable:唯一性與可空性length、precision、scale:長度、精度、刻度insertable、updatable:是否可插入/更新JPA 支援兩種註解風格,但在同一實體類中只能二擇一:
兩種方式映射結果相同,開發者可依偏好選擇。
當資料庫既有結構不可變更,或需將一實體拆分儲存時,可使用 @SecondaryTable(JPA 2.0):
@Entity
@SecondaryTables({
@SecondaryTable(name="Address"),
@SecondaryTable(name="Comments")
})
public class Forum implements Serializable {
@Id @GeneratedValue
private Long id;
private String username;
private String password;
@Column(table="Address", length=100)
private String street;
@Column(table="Address", nullable=false)
private String city;
@Column(table="Address")
private String country;
@Column(table="Comments")
private String title;
@Column(table="Comments")
private String comments;
@Column(table="Comments")
private Integer commentsLength;
// Getters and Setters
}
未指定 table 屬性的欄位會儲存在主表中。
使用 @Embeddable 標註可嵌入類,@Embedded 在擁有者類中引用:
@Embeddable
public class Address implements Serializable {
private String street;
private String city;
private String province;
private String country;
// Getters and Setters
}
@Entity
public class Employee implements Serializable {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private String email;
private String cellPhone;
@Embedded
private Address address;
// Getters and Setters
}
嵌入類的屬性會被平鋪儲存在擁有者的表中。嵌入類的註解方式預設跟隨擁有者,但可透過 @Access(AccessType.PROPERTY) 獨立指定,建議預先設定以避免不同擁有者嵌入時發生衝突。
基礎映射是 ORM 中最核心的部分,實現資料庫表與類的一對一對應,雖未涉及表間關聯,但為繼承映射、關聯關係映射奠定基礎。熟練掌握基礎映射策略,是高效使用 JPA/Hibernate 的關鍵。