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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持Devmax。

使用JPA主键@Id,@IdClass,@Embeddable,@EmbeddedId问题的更多相关文章

  1. Spring Data JPA系列JpaSpecificationExecutor用法详解

    这篇文章主要为大家介绍了Spring Data JPA系列JpaSpecificationExecutor用法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Spring Boot 整合持久层之Spring Data JPA

    在介绍Spring Data JPA的时候,我们首先认识下Hibernate。Hibernate是数据访问解决技术的绝对霸主,使用O/R映射技术实现数据访问,O/R映射即将领域模型类和数据库的表进行映射,通过程序操作对象而实现表数据操作的能力,让数据访问操作无须关注数据库相关的技术

  3. 使用JPA插入枚举类型字段

    这篇文章主要介绍了使用JPA插入枚举类型字段,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  4. 使用JPA单项一对多外键关联

    这篇文章主要介绍了使用JPA单项一对多外键关联,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  5. 使用spring jpa 如何给外键赋值

    这篇文章主要介绍了使用spring jpa 如何给外键赋值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  6. Android中@id和@+id及@android:id的区别介绍

    这篇文章主要给大家介绍了关于Android中@id和@+id及@android:id的区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  7. Spring JPA 增加字段执行异常问题及解决

    这篇文章主要介绍了Spring JPA 增加字段执行异常问题及解决,具有很好的参考价值,

  8. Spring Data JPA踩坑记录(@id @GeneratedValue)

    这篇文章主要介绍了Spring Data JPA踩坑记录(@id @GeneratedValue),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  9. Spring Boot深入学习数据访问之Spring Data JPA与Hibernate的应用

    Spring Data JPA是Spring Data的子项目,在使用Spring Data JPA之前,先了解一下Hibernate,因为Spring Data JPA是由Hibernate默认实现的

  10. 使用JPA双向多对多关联关系@ManyToMany

    这篇文章主要介绍了使用JPA双向多对多关联关系@ManyToMany,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部