常用 JPA annotation 參考

1.@Entity

     通過註釋@Entity或者(@Entity())表示被標示的類對應數據庫中的一張表。

@Entity
public class TravelProfile {
...
}

上面的例子告訴O/R映射引擎,類TravelProfile是可以持久化的,同時它對應數據庫中的一張表。但是它沒有指明對應哪個數據庫中的哪張表。

2.元數據映射標記
2.1 @Table

@Table()標記爲實體初始化一張表,定義如下:
@Target({TYPE}) @Retention(RUNTIME)
public @interface Table {
	String name() default "";
	String catalog() default "";
	String schema() default "";
	UniqueConstraint[] uniqueConstraints() default {};
}
Name:指明表的名字。(可選)
Catalog:表示表的catalog.(可選)
Schema:表示表的schema.(可選)
uniqueConstraints:制定表的唯一約束。(可選)
因爲所有的屬性都是可選的,也就是說@Table可以在進行映射的時候可以不標明。當不標明的情況下表的名字就是實體的類名。表屬於的schema就是所屬實體單元集的schema(就是當前連接數據庫的用戶)。
下面給出的例子中,指明表爲CUST,所屬的schema爲RECORDS:
@Entity
@Table(name="CUST", schema="RECORDS")
public class Customer { ... }

2.2 @UniqueConstraint標記
@UniqueConstraint用來指定表字段的唯一約束,定義如下:
@Target({}) @Retention(RUNTIME)
public @interface UniqueConstraint {
	String[] columnNames();
}
columnNames:制定唯一約束的字段。
@Entity
@Table(
name="EMPLOYEE",
uniqueConstraints=
@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)
public class Employee { ... }
上面的例子,唯一約束標記指定字段EMP_ID和字段EMP_NAME在表中EMPLOYEE中是唯一的。
2.3@Column標記
@Column標記把實體的屬性或域映射到表的字段,當沒有在實體的屬性或域中使用該標記那數據庫的對應表的字段名就是實體的屬性名或域名。其定義爲:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Column {
String name() default "";
	boolean unique() default false;
	boolean nullable() default true;
	boolean insertable() default true;
	boolean updatable() default true;
	String columnDefinition() default "";
	String table() default "";
	int length() default 255;
	int precision() default 0; // decimal precision
	int scale() default 0; // decimal scale
}
Name:指定字段名。
Unique:指明該字段是否唯一,默認爲false。
Nullable:指明是否可以爲空,默認是true。
Insertable:指明該字段在產生SQL INSERT語句中是否產生該字段。
Updatable:指明該字段在產生SQL INSERT語句中是否產生該字段。
columnDefinition:指定產生表的時候,使用它指定該字段一些屬性。
Table:當一個實體對應多個表的時候,指定該字段屬於哪個表。
Length:制定該字段的長度(只有在字段爲字符類型的纔有用),默認是255。
Precision: 指明字段的精度(在字段爲decimal類型的時候使用),默認是0
Scale:爲字段爲number型指定標量,默認爲0。
下面給出例子:
@Column(name="DESC", nullable=false, length=512)
public String getDescription() { return description; }

@Column(name="DESC",
columnDefinition="CLOB NOT NULL",
table="EMP_DETAIL")
@Lob
public String getDescription() { return description; }

@Column(name="ORDER_COST", updatable=false, precision=12, scale=2)
public BigDecimal getCost() { return cost; }

2.4@JoinColumn標記

@JoinColumn標記用來映射實體之間的關聯關係,定義如下:

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface JoinColumn {
	String name() default "";
	String referencedColumnName() default "";
	boolean unique() default false;
	boolean nullable() default true;
	boolean insertable() default true;
	boolean updatable() default true;
	String columnDefinition() default "";
	String table() default "";
}

Name:指定外鍵字段名,缺省的名字是被引用實體在引用實體內部的屬性標量名或域名加上下劃線”_”,再加上被引用實體的主鍵字段名構成。

ReferencedColumnName:被引用表的字段,如果沒有那缺省的就是該表的主鍵。
Unique:指明該字段是否唯一,默認爲false。
Nullable:外鍵是否可以爲空,默認是true。
Insertable:指明該字段在產生SQL INSERT語句中是否產生該字段。
Updatable:指明該字段在產生SQL INSERT語句中是否產生該字段。
columnDefinition:指定產生表的時候,使用它指定該字段一些屬性。
Table:當一個實體對應多個表的時候,指定該字段屬於哪個表。
下面例子的多對一關係中,指明瞭被引用實體在本實體的外鍵爲ADDR_ID。
@ManyToOne
@JoinColumn(name="ADDR_ID")
public Address getAddress() { return address; }


2.5@JoinColumns標記

@JoinColumns標記用在符合外鍵的時候,這個時候屬性name和referencedColumnName必須在@JoinColumn中進行初始化。例如:
@ManyToOne
@JoinColumns({
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
})
public Address getAddress() { return address; }

2.6@Id標記
@Id標記把實體屬性或域映射到表的主鍵。其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Id {}
下面例子通過標記@Id初始化實體的主鍵爲id,也可以通過加上標記@Column(name=”PrimaryKey”)自定義表的主鍵。
@Id
public Long getId() { return id; }

2.7@GeneratedValue標記
提供產生主鍵的策略,這就意味着它只能在出現標記@Id的情況下使用。其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface GeneratedValue {
	GenerationType strategy() default AUTO;
	String generator() default "";
}

public enum GenerationType { TABLE, SEQUENCE, IDENTITY, AUTO };
策略類型爲枚舉類型,共有四種類型分別爲:TABLE, SEQUENCE, IDENTITY, AUTO。
TABLE:提示持久化引擎實現者,使用數據庫的表來產生和維護主鍵。
SEQUENCE和IDENTITY:分別指定使用當前數據庫的序列號和標識字段來產生唯一表識。
AUTO:制定持久化引擎實現者,爲不同的數據庫選擇合適的策略產生唯一標識。

Generator:制定主鍵產生器,默認有持久化實現者提供。例如:
@Id
@GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
@Column(name="CUST_ID")
public Long getId() { return id; }

@Id
@GeneratedValue(strategy=TABLE, generator="CUST_GEN")
@Column(name="CUST_ID")
Long id;
2.8@IdClass標記
   這個標記用來指定一個實體類作爲一個另外一個實體的主鍵。這個時候要求實體的複合主鍵的每個屬性或域必須和複合主鍵類對應的屬性或域是一樣的。其定義如下:
@Target({TYPE}) @Retention(RUNTIME)
public @interface IdClass {
Class value();
}
下面例子中,複合主鍵類爲EmployeePK,包含域empName和birthday類型分別爲String,Date。
@IdClass(com.jl.hr.EmployeePK.class)
@Entity
public class Employee {
@Id String empName;
@Id Date birthDay;


2.9@Transient標記

標記指示實體的屬性或域是非持久化的。其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Transient {}
下面的例子說明實體 Employee的域currentUser是非持久化的。
@Entity
public class Employee {
@Id int id;
@Transient User currentUser;
...
}
2.10@Version標記
初始化實體的樂觀鎖的值,這個標記在大量併發訪問的實體中非常有用。如果要對實體使用這個標記那最好的策略是一個實體使用一個@Version標 記,同時這個標記對應字段的類型一般爲:int,Integer,short,Short,long,Long,Timestamp中的一種。其定義如 下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Version {}
給出相關的例子如下:
@Version
@Column(name="OPTLOCK")
protected int getVersionNum() { return versionNum; }
2.11@Lob標記
此標記初始化實體的屬性或域映射成數據庫支持的大對象類型。大對象可以是字符也可以是二進制類型。除了字符串和字符類型的默認映射成Blob類型,其它的類型根據實體屬性或域的類型來決定數據庫大對象的類型。例如:
@Lob
@Column(name="REPORT")
protected String report;

@Lob @Basic(fetch=LAZY)
@Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")
protected byte[] pic;
2.12@Enumerated標記
用來指定實體持久化屬性的爲枚舉類型,其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Enumerated {
EnumType value() default ORDINAL;
}

public enum EnumType {
ORDINAL,
STRING
}
如果標記沒有顯性給出或者EnumType沒有指定,那枚舉類型默認爲ORDINAL數字標識。例如:
public enum EmployeeStatus {FULL_TIME, PART_TIME, CONTRACT}
public enum SalaryRate {JUNIOR, SENIOR, MANAGER, EXECUTIVE}
@Entity public class Employee {
...
public EmployeeStatus getStatus() {...}
@Enumerated(STRING)
public SalaryRate getPayScale() {...}
...
}
上面例子中,定義了兩個枚舉類型EmployeeStatus和SalaryRate。在實體兩個屬性status類型爲 EmployeeStatus,而payScale爲SalaryRate類型。其中一個顯性給出了標記@Enumerated(STRING)來說明枚 舉類型的值當成字符串使用,而默認的是從1開始的數字來標識的。也可以通過標記@Enumerated(ORDINAL)指示枚舉裏面類型的值是數字類型 的。例如在EmployeeStatus
中的FULL_TIME, PART_TIME, CONTRACT分別代表的數字是1,2,3,4而SalaryRate
中的JUNIOR, SENIOR, MANAGER, EXECUTIVE代表的分別是字符串“JUNIOR”, “SENIOR”, “MANAGER”, “EXECUTIVE”。

2.13@ManyToOne標記
   當實體之間的關係是多對一的時候,該標記定義一個單值的字段與其它實體相關聯。其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
	Class targetEntity() default void.class;
	CascadeType[] cascade() default {};
	FetchType fetch() default EAGER;
	boolean optional() default true;
}

public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH};
targetEntity:表示相關聯的實體類。
Cascade:級聯操作選項,PERSIST, MERGE, REMOVE, REFRESH分別對應增加,更新,刪除和查找的聯級設置選項。如果選擇ALL就使得前面這些聯級都生效,也就是cascade=ALL 等同於cascade={PERSIST, MERGE, REMOVE,REFRESH}
Fetch:制定關聯實體的加載方式,包括EAGER和LAZY兩種方式。當爲EAGER選選項的時候,當查詢實體的時候會把它相關聯的實體實例也加載。當爲LAZY的時候加載實體實例的時候與之相關聯的實體實例不會加載,默認爲EAGER。
Optional:指定關聯實體關係是否可以爲空,默認是爲true。當爲false的時候,那當有實體實例的存在總會有與之相關實體實例的存在。
例如:
@ManyToOne(optional=flase)
@JoinColumn(name="CUST_ID", nullable=false, updatable=false)
public Customer getCustomer() { return customer; }


2.14@OneToOne標記

標記定義實體一對一關係的聯繫,通過一個字段來進行關聯。其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
String mappedBy() default "";
}
前面四個選項和8.2.13中的意義是一樣的。
mappedBy:代表這個屬性或域是關係的擁有者,也就是說mappedBy選擇應該是在非關係擁有者方纔會出現。所謂關係的擁有者就是在表中包含了關係字段的那張表。
現在假設有實體Customer和實體CustomerRecoder它們之間是一對一的關係,同時實體Customer是關係的擁有者。這個時候通過標記@OneToOne來完成關聯,在實體Customer相關代碼如下:
@OneToOne(optional=false)
@JoinColumn(
name="CUSTREC_ID", unique=true, nullable=false, updatable=false)
public CustomerRecord getCustomerRecord() { return customerRecord; }
在實體CustomerRecord相關代碼如下:
@OneToOne(optional=false, mappedBy="customerRecord")
public Customer getCustomer() { return customer; }
因爲CustomerRecord是關係的非擁有者所有mappedBy只能在這邊出現。

2.15@OneToMany標記
用來標記實體之間的一對多的關係,其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
	Class targetEntity() default void.class;
	CascadeType[] cascade() default {};
	FetchType fetch() default LAZY;
	String mappedBy() default "";
}
值得注意的是表示關聯實體的集合要使用範形來制定集合內部的關聯實體,否則必須要指定targetEntity的實體類型。Fetch類型默認爲LAZY而@OneToOne和ManyToOne則默認的爲EAGER。
假設現在有實體Customer和Order它們之間的關係是一對多的關係,同時Order是關係的擁有者。
在實體Customer中的代碼爲:
@OneToMany(cascade=ALL, mappedBy=”customer”)
public Set<Order> getOrders() { return orders; }
在實體Order中的代碼爲:
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() { return customer; }


2.16@JoinTable標記

用來映射多對多和單項的一對多關係,當不是用該標記的時候會根據默認的映射原則產生關係連接表。其定義如下:
public @interface JoinTable {
	String name() default "";
	String catalog() default "";
	String schema() default "";
	JoinColumn[] joinColumns() default {};
	JoinColumn[] inverseJoinColumns() default {};
	UniqueConstraint[] uniqueConstraints() default {};
}
Name:指定連接表的名字。
Catalog:指定表所屬的catalog。
Schema:指定表所屬的schema。
joinColumns:指定關係擁有方作爲外鍵的主鍵。
inverseJoinColumns:指定關係非擁有方作爲外鍵的主鍵。
uniqueConstraints:指定表中的唯一約束。
例如:
@JoinTable(
name="CUST_PHONE",
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
)
上面例子,連接表的名字爲CUST_PHONE裏面有兩個外鍵,一個來自關係擁有方的主鍵ID對應外鍵爲CUST_ID;另一個是來自於關係的非擁有方的主鍵ID對應外鍵爲PHONE_ID。
2.17@ManyToMany標記

標記實體之間的多對多的關係,如果不通過範形來制定集合中的關聯實體類型那必須指定相應的關聯實體類型。其定義如下:

@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
	Class targetEntity() default void.class;
	CascadeType[] cascade() default {};
	FetchType fetch() default LAZY;
	String mappedBy() default "";
}

各個屬性的意義和標記@OneToMany是一樣的,請參照8.2.1.15。

如果關聯是雙向的兩邊都可以是關係的擁有方,可以通過標記@JoinTable來制定關係擁有方,請參照2.16。
設有實體Customer和PhoneNumber,則它們的關係映射代碼如下:
在實體Customer中爲:
@ManyToMany
@JoinTable(name="CUST_PHONES")
public Set<PhoneNumber> getPhones() { return phones; }
在實體PhoneNumber中爲:
@ManyToMany(mappedBy="phones")
public Set<Customer> getCustomers() { return customers; }
在實際開發中,對於多對多關係我們經常使用標記@JoinTable來制定關係的擁有方,則對於上面的映射爲:
@ManyToMany
@JoinTable(
name="CUST_PHONE",
joinColumns=
@JoinColumn(name="CUST_ID", referencedColumnName="ID"),
inverseJoinColumns=
@JoinColumn(name="PHONE_ID", referencedColumnName="ID")
)
public Set<PhoneNumber> getPhones() { return phones; }

@ManyToMany(mappedBy="phones")
public Set<Customer> getCustomers() { return customers; }

2.18@OrderBy標記
指定批量查詢實例實例的時候指定排序的屬性或域,其定義如下:
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OrderBy {
String value() default "";
}
對於使用該標記對應的字段必須是可以比較的,默認的使用的是ASC也可以根據需求改變成DESC。當沒有指定value的時候,那默認的就是對實體的主鍵進行排序,例如:
@Entity public class Course {
...
@ManyToMany
@OrderBy("lastname ASC")
public List<Student> getStudents() {...};
	...
}
@Entity public class Student {
...
@ManyToMany(mappedBy="students")
@OrderBy // PK is assumed
public List<Course> getCourses() {...};
	...
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章