使用JPA主键@Id,@IdClass,@Embeddable,@EmbeddedId问题

网友投稿 506 2022-07-24


目录JPA主键@Id,@IdClass,@Embeddable,@EmbeddedId1、自动主键2、应用设置主键3、复合主键4、嵌入式主键@EmbeddedId和@IdClass的区别@idClass@EmbeddedId

JPA主键@Id,@IdClass,@Embeddable,@EmbeddedId

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类。

4、嵌入式主键

表示复合主键的另一种方法是使用可嵌入的类:

@Entity

public class Project {

@EmbeddedId ProjectId id;

}

@Embeddable

Class ProjectId {

int departmentId;

long projectId;

}

主键字段是在可嵌入类中定义的。

该实体包含一个单独的主键字段,该字段用@EmbeddedId 注释,并包含一个可嵌入类的实例。

当使用这个表单时,没有定义一个单独的ID类,因为可嵌入的类本身可以表示完整的主键值。

@EmbeddedId和@IdClass的区别

@idClass

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

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

它是一个普通的旧式 Java 对象 (POJO) 类。它必须为 public,并且必须有一个 public 无参数构造函数。如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。它必须是可序列化的。它必须定义 equals 和 hashCode 方法。这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。它的字段或属性的类型和名称必须与使用 @Id 进行批注的实体主键字段或属性的类型和名称相对应。

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

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

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

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

它是一个普通的旧式 Java 对象 (POJO) 类。它必须为 public,并且必须有一个 public 无参数构造函数。如果使用基于属性的访问,则主键类的属性必须为 public 或 protected。它必须是可序列化的。它必须定义 equals 和 hashCode 方法。这些方法的值相等性的语义必须与键映射到的数据库类型的数据库相等性一致。

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 rolikWdqefZeId;

}

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;

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现日历功能
下一篇:Spring中Bean的三种实例化方式详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~