天天看点

Jpa 主键@Id @IdClass 以及 @EmbeddedId和@idClass的区别@EmbeddedId和@idClass的区别

1、自动主键 

默认情况下,主键是一个连续的64位数字(long),它由ObjectDB自动为存储在数据库中的每个新实体对象自动设置。数据库中的第一个实体对象的主键是1,第二个实体对象的主键是2等等。当从数据库中删除实体对象时,主键值不会被回收。 

一个实体的主键值可以通过声明一个主键字段来访问:

@Entity
public class Project {
    @Id @GeneratedValue long id; // still set automatically
}
           

@id标注将字段标记为一个主键字段。当定义主键字段时,主键值将被ObjectDB自动注入到该字段中。 

@generatedvalue注释指定主键是由ObjectDB自动分配的 

2、应用设置主键 

如果一个实体有一个没有@generatedvalue标记的主键字段,则不会生成自动主键值,并且应用程序负责通过初始化主键字段来设置主键。这必须在持久化实体对象的任何尝试之前完成。

@Entity
public class Project {
    @Id long id; // must be initialized by the application
}
           

应用程序设置的主键字段可以有以下类型: 

● 原始类型: 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. 

● 枚举类型 

● 引用一个实体对象 

3、复合主键 

复合主键由多个主键字段组成。每个主键字段必须是上面列出的支持类型之一。 

例如,以下项目实体类的主键由两个字段组成:

@Entity @IdClass(ProjectId.class)
public class Project {
    @Id int departmentId;
    @Id long projectId;
}
           

当一个实体有多个主键字段时,JPA需要定义一个特殊的ID类,该类是使用@idclass注释附加到实体类的。ID类反映了主键字段,它的对象可以表示主键值:

Class ProjectId {
    int departmentId;
    long projectId;
}
           

ObjectDB不强制定义ID类。但是,如果实体对象必须按照检索实体部分中所示的主键来检索实体对象,那么就需要ID类。

转发:https://blog.csdn.net/tracycater/article/details/78319021

================================================================================================

@EmbeddedId和@idClass的区别

@idClass

使复合主键类成为非嵌入类,使用 

@IdClass

 批注为实体指定一个复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。

复合主键类具有下列特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类。
  • 它必须为 public,并且必须有一个 public 无参数构造函数。
  • 如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。
  • 它必须是可序列化的。
  • 它必须定义 

    equals

     和 

    hashCode

     方法。

    这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

  • 它的字段或属性的类型和名称必须与使用 @Id 进行批注的实体主键字段或属性的类型和名称相对应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59

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;

}  

}

  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

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

使复合主键类成为由实体拥有的嵌入类

使用 

@EmbeddedId

 批注指定一个由实体拥有的可嵌入复合主键类(通常由两个或更多基元类型或 JDK 对象类型组成)。从原有数据库映射时(此时数据库键由多列组成),通常将出现复合主键。

复合主键类具有下列特征:

  • 它是一个普通的旧式 Java 对象 (POJO) 类。
  • 它必须为 public,并且必须有一个 public 无参数构造函数。
  • 如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。
  • 它必须是可序列化的。
  • 它必须定义 

    equals

     和 

    hashCode

     方法。

    这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

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;

}

}

  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

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;

}

}

  作者: lost blog

      出处: http://www.cnblogs.com/JAYIT/

     关于作者:专注服务器端开发

继续阅读