使用JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId問題
JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId
1、自動主鍵
默認(rèn)情況下,主鍵是一個連續(xù)的64位數(shù)字(long),它由ObjectDB自動為存儲在數(shù)據(jù)庫中的每個新實(shí)體對象自動設(shè)置。
數(shù)據(jù)庫中的第一個實(shí)體對象的主鍵是1,第二個實(shí)體對象的主鍵是2等等。
當(dāng)從數(shù)據(jù)庫中刪除實(shí)體對象時,主鍵值不會被回收。
一個實(shí)體的主鍵值可以通過聲明一個主鍵字段來訪問:
@Entity public class Project { ? ? @Id @GeneratedValue long id; // still set automatically }
@id
標(biāo)注將字段標(biāo)記為一個主鍵字段。當(dāng)定義主鍵字段時,主鍵值將被ObjectDB自動注入到該字段中。@generatedvalue
注釋指定主鍵是由ObjectDB自動分配的
2、應(yīng)用設(shè)置主鍵
如果一個實(shí)體有一個沒有@generatedvalue標(biāo)記的主鍵字段,則不會生成自動主鍵值,并且應(yīng)用程序負(fù)責(zé)通過初始化主鍵字段來設(shè)置主鍵。這必須在持久化實(shí)體對象的任何嘗試之前完成。
@Entity public class Project { ? ? @Id long id; // must be initialized by the application }
應(yīng)用程序設(shè)置的主鍵字段可以有以下類型:
● 原始類型: boolean, byte, short, char, int, long, float, double.
● java.lang包中的包裝類型:Byte, Short, Character, Integer, Long, Float, Double.
● java.math.BigInteger, java.math.BigDecimal.
● java.lang.String.
● java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp.
● 枚舉類型
● 引用一個實(shí)體對象
3、復(fù)合主鍵
復(fù)合主鍵由多個主鍵字段組成。每個主鍵字段必須是上面列出的支持類型之一。
例如,以下項(xiàng)目實(shí)體類的主鍵由兩個字段組成:
@Entity @IdClass(ProjectId.class) public class Project { ? ? @Id int departmentId; ? ? @Id long projectId; }
當(dāng)一個實(shí)體有多個主鍵字段時,JPA需要定義一個特殊的ID類,該類是使用@idclass注釋附加到實(shí)體類的。ID類反映了主鍵字段,它的對象可以表示主鍵值:
Class ProjectId { ? ? int departmentId; ? ? long projectId; }
ObjectDB不強(qiáng)制定義ID類。但是,如果實(shí)體對象必須按照檢索實(shí)體部分中所示的主鍵來檢索實(shí)體對象,那么就需要ID類。
4、嵌入式主鍵
表示復(fù)合主鍵的另一種方法是使用可嵌入的類:
@Entity public class Project { ? ? @EmbeddedId ProjectId id; } @Embeddable Class ProjectId { ? ? int departmentId; ? ? long projectId; }
主鍵字段是在可嵌入類中定義的。
該實(shí)體包含一個單獨(dú)的主鍵字段,該字段用@EmbeddedId 注釋,并包含一個可嵌入類的實(shí)例。
當(dāng)使用這個表單時,沒有定義一個單獨(dú)的ID類,因?yàn)榭汕度氲念惐旧砜梢员硎就暾闹麈I值。
@EmbeddedId和@IdClass的區(qū)別
@idClass
使復(fù)合主鍵類成為非嵌入類,使用 @IdClass 批注為實(shí)體指定一個復(fù)合主鍵類(通常由兩個或更多基元類型或 JDK 對象類型組成)。從原有數(shù)據(jù)庫映射時(此時數(shù)據(jù)庫鍵由多列組成),通常將出現(xiàn)復(fù)合主鍵。
復(fù)合主鍵類具有下列特征:
- 它是一個普通的舊式 Java 對象 (POJO) 類。
- 它必須為 public,并且必須有一個 public 無參數(shù)構(gòu)造函數(shù)。
- 如果使用基于屬性的訪問,則主鍵類的屬性必須為 public 或 protected。
- 它必須是可序列化的。
- 它必須定義 equals 和 hashCode 方法。
- 這些方法的值相等性的語義必須與鍵映射到的數(shù)據(jù)庫類型的數(shù)據(jù)庫相等性一致。
- 它的字段或?qū)傩缘念愋秃兔Q必須與使用 @Id 進(jìn)行批注的實(shí)體主鍵字段或?qū)傩缘念愋秃兔Q相對應(yīng)。
package com.model; import java.io.Serializable; public class SysUserRoleId implements Serializable{? ? ? /** ? ? ?* ? ? ?*/ ? ? private static final long serialVersionUID = 2606793267849167078L; ? ? private Long userId; ? ? private Long roleId; ? ? ? ? ? @Override ? ? public int hashCode(){ ? ? ? ? int result = 1; ? ? ? ? result = userId.hashCode()+roleId.hashCode(); ? ? ? ? return result; ? ? } ? ? ? ? ? @Override ? ? public boolean equals(Object obj){ ? ?? ? ? ? ? if(obj == null){ ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? ? ? ? ? ? if(this == obj){ ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? ? ? ? ? ? if(getClass() != obj.getClass()){ ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? ? ? ? ? ? final SysUserRoleId other = (SysUserRoleId) obj; ? ? ? ? if(other.getUserId().equals(this.userId) && other.getRoleId().equals(this.roleId)){ ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? ? ? ? ? ? return false; ? ? } ? ? ? ? ? public Long getUserId() { ? ? ? ? return userId; ? ? } ? ? public void setUserId(Long userId) { ? ? ? ? this.userId = userId; ? ? } ? ? public Long getRoleId() { ? ? ? ? return roleId; ? ? } ? ? public void setRoleId(Long roleId) { ? ? ? ? this.roleId = roleId; ? ? } ? }
package com.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.IdClass; import javax.persistence.Table; ?? @Entity @Table(name="SYS_USER_ROLE") @IdClass(SysUserRoleId.class) public class SysUserRole { ? ? private Long userId; ? ? private Long roleId; ? ? public SysUserRole(){? ? ? } ? ? ? ? ? public SysUserRole(Long userId,Long roleId){ ? ? ? ? this.userId = userId; ? ? ? ? this.roleId = roleId; ? ? } ? ? ? ? ? @Id ? ? @Column(name="user_id") ? ? public Long getUserId() { ? ? ? ? return userId; ? ? } ? ? public void setUserId(Long userId) { ? ? ? ? this.userId = userId; ? ? } ? ? ? ? ? @Id ? ? @Column(name="role_id") ? ? public Long getRoleId() { ? ? ? ? return roleId; ? ? } ? ? public void setRoleId(Long roleId) { ? ? ? ? this.roleId = roleId; ? ? }? ?? }
@EmbeddedId
使復(fù)合主鍵類成為由實(shí)體擁有的嵌入類
使用 @EmbeddedId 批注指定一個由實(shí)體擁有的可嵌入復(fù)合主鍵類(通常由兩個或更多基元類型或 JDK 對象類型組成)。從原有數(shù)據(jù)庫映射時(此時數(shù)據(jù)庫鍵由多列組成),通常將出現(xiàn)復(fù)合主鍵。
復(fù)合主鍵類具有下列特征:
- 它是一個普通的舊式 Java 對象 (POJO) 類。
- 它必須為 public,并且必須有一個 public 無參數(shù)構(gòu)造函數(shù)。
- 如果使用基于屬性的訪問,則主鍵類的屬性必須為 public 或 protected。
- 它必須是可序列化的。
- 它必須定義 equals 和 hashCode 方法。
- 這些方法的值相等性的語義必須與鍵映射到的數(shù)據(jù)庫類型的數(shù)據(jù)庫相等性一致。
package com.model; import java.io.Serializable; import javax.persistence.Column; @SuppressWarnings("serial") public class SysOrganizationRolePKId implements Serializable{ ? ? private Long organizationId; ? ? private Long roleId; ? ? ? ? ? @Column(name="organization_id") ? ? public Long getOrganizationId() { ? ? ? ? return organizationId; ? ? } ? ? public void setOrganizationId(Long organizationId) { ? ? ? ? this.organizationId = organizationId; ? ? } ? ? ? ? ? @Column(name="role_id") ? ? public Long getRoleId() { ? ? ? ? return roleId; ? ? } ? ? public void setRoleId(Long roleId) { ? ? ? ? this.roleId = roleId; ? ? }??? ? }
package com.model; import java.io.Serializable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Table; ? @Entity @SuppressWarnings("serial") @Table(name="SYS_ORGANIZATION_ROLE") public class SysOrganizationRole implements Serializable{ ? ? private SysOrganizationRolePKId sysOrganizationRolePKId; ? ? ? @EmbeddedId ? ? public SysOrganizationRolePKId getSysOrganizationRolePKId() { ? ? ? ? return sysOrganizationRolePKId; ? ? } ? ? ? public void setSysOrganizationRolePKId( ? ? ? ? ? ? SysOrganizationRolePKId sysOrganizationRolePKId) { ? ? ? ? this.sysOrganizationRolePKId = sysOrganizationRolePKId; ? ? }??? }
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java判斷IP地址為內(nèi)網(wǎng)IP還是公網(wǎng)IP的方法
這篇文章主要介紹了Java判斷IP地址為內(nèi)網(wǎng)IP還是公網(wǎng)IP的方法,針對tcp/ip協(xié)議中保留的三個私有地址進(jìn)行判斷分析,是比較實(shí)用的技巧,需要的朋友可以參考下2015-01-01Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息
這篇文章主要介紹了Springboot如何使用OSHI獲取和操作系統(tǒng)和硬件信息問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10Java Swing JRadioButton單選按鈕具體使用
這篇文章主要介紹了Java Swing JRadioButton單選按鈕具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12windows下java環(huán)境變量的設(shè)置方法
在“系統(tǒng)變量”中,設(shè)置3項(xiàng)屬性,JAVA_HOME,PATH,CLASSPATH(大小寫無所謂),若已存在則點(diǎn)擊“編輯”,不存在則點(diǎn)擊“新建”2013-09-09java 刪除數(shù)組元素與刪除重復(fù)數(shù)組元素的代碼
在java中刪除數(shù)組元素與過濾重復(fù)數(shù)組元素我們都會需要去遍歷數(shù)組然后根據(jù)我們設(shè)置的值或方法進(jìn)行去除數(shù)組2013-10-10IDEA強(qiáng)制清除Maven緩存的實(shí)現(xiàn)示例
清除項(xiàng)目緩存是一個常見的操作,本文主要介紹了IDEA強(qiáng)制清除Maven緩存的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07java 中Comparable與Comparator詳解與比較
這篇文章主要介紹了java 中Comparable與Comparator詳解與比較的相關(guān)資料,需要的朋友可以參考下2017-04-04