使用JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId問(wèn)題
JPA主鍵@Id,@IdClass,@Embeddable,@EmbeddedId
1、自動(dòng)主鍵
默認(rèn)情況下,主鍵是一個(gè)連續(xù)的64位數(shù)字(long),它由ObjectDB自動(dòng)為存儲(chǔ)在數(shù)據(jù)庫(kù)中的每個(gè)新實(shí)體對(duì)象自動(dòng)設(shè)置。
數(shù)據(jù)庫(kù)中的第一個(gè)實(shí)體對(duì)象的主鍵是1,第二個(gè)實(shí)體對(duì)象的主鍵是2等等。
當(dāng)從數(shù)據(jù)庫(kù)中刪除實(shí)體對(duì)象時(shí),主鍵值不會(huì)被回收。
一個(gè)實(shí)體的主鍵值可以通過(guò)聲明一個(gè)主鍵字段來(lái)訪問(wèn):
@Entity
public class Project {
? ? @Id @GeneratedValue long id; // still set automatically
}@id標(biāo)注將字段標(biāo)記為一個(gè)主鍵字段。當(dāng)定義主鍵字段時(shí),主鍵值將被ObjectDB自動(dòng)注入到該字段中。@generatedvalue注釋指定主鍵是由ObjectDB自動(dòng)分配的
2、應(yīng)用設(shè)置主鍵
如果一個(gè)實(shí)體有一個(gè)沒(méi)有@generatedvalue標(biāo)記的主鍵字段,則不會(huì)生成自動(dòng)主鍵值,并且應(yīng)用程序負(fù)責(zé)通過(guò)初始化主鍵字段來(lái)設(shè)置主鍵。這必須在持久化實(shí)體對(duì)象的任何嘗試之前完成。
@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.
● 枚舉類型
● 引用一個(gè)實(shí)體對(duì)象
3、復(fù)合主鍵
復(fù)合主鍵由多個(gè)主鍵字段組成。每個(gè)主鍵字段必須是上面列出的支持類型之一。
例如,以下項(xiàng)目實(shí)體類的主鍵由兩個(gè)字段組成:
@Entity @IdClass(ProjectId.class)
public class Project {
? ? @Id int departmentId;
? ? @Id long projectId;
}當(dāng)一個(gè)實(shí)體有多個(gè)主鍵字段時(shí),JPA需要定義一個(gè)特殊的ID類,該類是使用@idclass注釋附加到實(shí)體類的。ID類反映了主鍵字段,它的對(duì)象可以表示主鍵值:
Class ProjectId {
? ? int departmentId;
? ? long projectId;
}ObjectDB不強(qiáng)制定義ID類。但是,如果實(shí)體對(duì)象必須按照檢索實(shí)體部分中所示的主鍵來(lái)檢索實(shí)體對(duì)象,那么就需要ID類。
4、嵌入式主鍵
表示復(fù)合主鍵的另一種方法是使用可嵌入的類:
@Entity
public class Project {
? ? @EmbeddedId ProjectId id;
}
@Embeddable
Class ProjectId {
? ? int departmentId;
? ? long projectId;
}主鍵字段是在可嵌入類中定義的。
該實(shí)體包含一個(gè)單獨(dú)的主鍵字段,該字段用@EmbeddedId 注釋,并包含一個(gè)可嵌入類的實(shí)例。
當(dāng)使用這個(gè)表單時(shí),沒(méi)有定義一個(gè)單獨(dú)的ID類,因?yàn)榭汕度氲念惐旧砜梢员硎就暾闹麈I值。
@EmbeddedId和@IdClass的區(qū)別
@idClass
使復(fù)合主鍵類成為非嵌入類,使用 @IdClass 批注為實(shí)體指定一個(gè)復(fù)合主鍵類(通常由兩個(gè)或更多基元類型或 JDK 對(duì)象類型組成)。從原有數(shù)據(jù)庫(kù)映射時(shí)(此時(shí)數(shù)據(jù)庫(kù)鍵由多列組成),通常將出現(xiàn)復(fù)合主鍵。
復(fù)合主鍵類具有下列特征:
- 它是一個(gè)普通的舊式 Java 對(duì)象 (POJO) 類。
- 它必須為 public,并且必須有一個(gè) public 無(wú)參數(shù)構(gòu)造函數(shù)。
- 如果使用基于屬性的訪問(wèn),則主鍵類的屬性必須為 public 或 protected。
- 它必須是可序列化的。
- 它必須定義 equals 和 hashCode 方法。
- 這些方法的值相等性的語(yǔ)義必須與鍵映射到的數(shù)據(jù)庫(kù)類型的數(shù)據(jù)庫(kù)相等性一致。
- 它的字段或?qū)傩缘念愋秃兔Q必須與使用 @Id 進(jìn)行批注的實(shí)體主鍵字段或?qū)傩缘念愋秃兔Q相對(duì)應(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 批注指定一個(gè)由實(shí)體擁有的可嵌入復(fù)合主鍵類(通常由兩個(gè)或更多基元類型或 JDK 對(duì)象類型組成)。從原有數(shù)據(jù)庫(kù)映射時(shí)(此時(shí)數(shù)據(jù)庫(kù)鍵由多列組成),通常將出現(xiàn)復(fù)合主鍵。
復(fù)合主鍵類具有下列特征:
- 它是一個(gè)普通的舊式 Java 對(duì)象 (POJO) 類。
- 它必須為 public,并且必須有一個(gè) public 無(wú)參數(shù)構(gòu)造函數(shù)。
- 如果使用基于屬性的訪問(wèn),則主鍵類的屬性必須為 public 或 protected。
- 它必須是可序列化的。
- 它必須定義 equals 和 hashCode 方法。
- 這些方法的值相等性的語(yǔ)義必須與鍵映射到的數(shù)據(jù)庫(kù)類型的數(shù)據(jù)庫(kù)相等性一致。
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;
? ? }???
}以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
教你利用springboot集成swagger并生成接口文檔
有很多小伙伴不會(huì)利用springboot集成swagger并生成接口文檔,今天特地整理了這篇文章,文中有非常詳細(xì)的代碼圖文介紹及代碼示例,對(duì)不會(huì)這個(gè)方法的小伙伴們很有幫助,需要的朋友可以參考下2021-05-05
詳解Java TCC分布式事務(wù)實(shí)現(xiàn)原理
這篇文章主要介紹了詳解Java TCC分布式事務(wù)實(shí)現(xiàn)原理,對(duì)分布式事務(wù)感興趣的同學(xué),一定要看一下2021-04-04
Java聊天室之實(shí)現(xiàn)接收和發(fā)送Socket
這篇文章主要為大家詳細(xì)介紹了Java簡(jiǎn)易聊天室之實(shí)現(xiàn)接收和發(fā)送Socket功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下2022-10-10
MyBatis之一級(jí)緩存和二級(jí)緩存問(wèn)題
這篇文章主要介紹了MyBatis之一級(jí)緩存和二級(jí)緩存問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
java實(shí)現(xiàn)分布式項(xiàng)目搭建的方法
這篇文章主要介紹了java實(shí)現(xiàn)分布式項(xiàng)目搭建的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
詳解Spring系列之@ComponentScan批量注冊(cè)bean
本文介紹各種@ComponentScan批量掃描注冊(cè)bean的基本使用以及進(jìn)階用法和@Componet及其衍生注解使用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-02-02
如何使用Java redis實(shí)現(xiàn)發(fā)送手機(jī)驗(yàn)證碼功能
這篇文章主要介紹了如何使用Java redis實(shí)現(xiàn)發(fā)送手機(jī)驗(yàn)證碼功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
.properties文件讀取及占位符${...}替換源碼解析
本篇文章主要介紹了.properties文件讀取及占位符${...}替換源碼解析的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-05-05
AbstractQueuedSynchronizer(AQS)鎖狀態(tài)同步和排隊(duì)管理
這篇文章主要介紹了為大家AbstractQueuedSynchronizer(AQS)鎖狀態(tài)同步和排隊(duì)管理源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

