Java主键生成之@Id和@GeneratedValue使用详解

 更新时间:2025年05月10日 15:05:38   作者:程序媛学姐  
这篇文章主要介绍了Java主键生成之@Id和@GeneratedValue的使用,@Id和@GeneratedValue注解就是JPA中用于定义主键和主键生成策略的关键注解,理解这两个注解的使用和不同的主键生成策略,对于开发高效、稳定的数据持久化应用至关重要,需要的朋友可以参考下

引言

在Java的企业级开发中,数据库操作是必不可少的一部分。而在数据库表中,主键是唯一标识每条记录的重要字段。在使用JPA(Java Persistence API)进行对象 - 关系映射时,需要为实体类指定主键,并确定主键的生成策略。@Id@GeneratedValue注解就是JPA中用于定义主键和主键生成策略的关键注解。理解这两个注解的使用和不同的主键生成策略,对于开发高效、稳定的数据持久化应用至关重要。

一、@Id注解的作用

@Id注解是JPA中用于标识实体类的属性为主键的注解。在JPA实体类中,必须有一个属性被@Id注解标记,以此来指定该属性对应数据库表中的主键列。主键在数据库中具有唯一性,用于唯一标识表中的每一条记录。以下是一个简单的示例:

import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Employee {
    @Id
    private Long id;
    private String name;
    private String department;
    public Employee() {
    }
    public Employee(Long id, String name, String department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDepartment() {
        return department;
    }
    public void setDepartment(String department) {
        this.department = department;
    }
}

在这个示例中,id属性被@Id注解标记为主键。

二、@GeneratedValue注解概述

@GeneratedValue注解用于指定主键的生成策略。当使用@Id注解标记了主键属性后,可以使用@GeneratedValue注解来定义该主键的值是如何生成的。@GeneratedValue注解有两个重要的属性:strategygeneratorstrategy属性用于指定主键生成策略,generator属性用于指定自定义的主键生成器。

三、不同的主键生成策略

1. GenerationType.AUTO

GenerationType.AUTO@GeneratedValue注解的默认策略。JPA会根据底层数据库的特性自动选择合适的主键生成策略。例如,对于支持自增主键的数据库(如MySQL),JPA可能会选择自增策略;对于不支持自增主键的数据库,可能会选择其他策略。示例如下:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private double price;
    public Product() {
    }
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
}

在这个示例中,id属性的主键生成策略为AUTO

2. GenerationType.IDENTITY

GenerationType.IDENTITY策略适用于支持自增主键的数据库,如MySQL、SQL Server等。使用该策略时,数据库会自动为新插入的记录生成一个唯一的自增主键值。示例如下:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    public Customer() {
    }
    public Customer(String name, String email) {
        this.name = name;
        this.email = email;
    }
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}

在这个示例中,id属性的主键生成策略为IDENTITY,数据库会自动为新插入的Customer记录生成自增的id值。

3. GenerationType.SEQUENCE

GenerationType.SEQUENCE策略适用于支持序列(Sequence)的数据库,如Oracle、PostgreSQL等。序列是数据库中用于生成唯一数字的对象。使用该策略时,需要在数据库中创建对应的序列,并在@GeneratedValue注解中指定序列的名称。示例如下:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq")
    @SequenceGenerator(name = "order_seq", sequenceName = "ORDER_SEQ", allocationSize = 1)
    private Long id;
    private String orderNumber;
    private double totalAmount;
    public Order() {
    }
    public Order(String orderNumber, double totalAmount) {
        this.orderNumber = orderNumber;
        this.totalAmount = totalAmount;
    }
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getOrderNumber() {
        return orderNumber;
    }
    public void setOrderNumber(String orderNumber) {
        this.orderNumber = orderNumber;
    }
    public double getTotalAmount() {
        return totalAmount;
    }
    public void setTotalAmount(double totalAmount) {
        this.totalAmount = totalAmount;
    }
}

在这个示例中,@SequenceGenerator注解定义了一个名为order_seq的序列生成器,sequenceName指定了数据库中序列的名称,allocationSize指定了每次从序列中获取的号码数量。

4. GenerationType.TABLE

GenerationType.TABLE策略使用一个数据库表来模拟序列的功能,以生成唯一的主键值。这种策略适用于不支持序列的数据库,或者需要在多个数据库之间保持主键生成的一致性。示例如下:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.TableGenerator;
@Entity
public class Supplier {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "supplier_gen")
    @TableGenerator(name = "supplier_gen", table = "ID_GENERATOR_TABLE", pkColumnName = "GEN_KEY", valueColumnName = "GEN_VALUE", pkColumnValue = "SUPPLIER_PK", allocationSize = 1)
    private Long id;
    private String name;
    private String contactInfo;
    public Supplier() {
    }
    public Supplier(String name, String contactInfo) {
        this.name = name;
        this.contactInfo = contactInfo;
    }
    // Getters and Setters
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContactInfo() {
        return contactInfo;
    }
    public void setContactInfo(String contactInfo) {
        this.contactInfo = contactInfo;
    }
}

在这个示例中,@TableGenerator注解定义了一个名为supplier_gen的表生成器,table指定了用于生成主键的表名,pkColumnNamevalueColumnName分别指定了主键列和值列的名称,pkColumnValue指定了该实体类对应的主键值。

总结

@Id@GeneratedValue注解是JPA中用于定义主键和主键生成策略的重要注解。@Id注解用于标识实体类的属性为主键,而@GeneratedValue注解则用于指定主键的生成策略。JPA提供了多种主键生成策略,包括AUTOIDENTITYSEQUENCETABLE,每种策略都有其适用的场景和数据库类型。开发者需要根据具体的数据库和业务需求选择合适的主键生成策略,以确保数据的完整性和一致性,同时提高开发效率。

以上就是Java主键生成之@Id和@GeneratedValue使用详解的详细内容,更多关于Java @Id和@GeneratedValue的资料请关注脚本之家其它相关文章!

相关文章

  • JpaRepository 实现简单条件查询

    JpaRepository 实现简单条件查询

    这篇文章主要介绍了JpaRepository 实现简单条件查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 深入学习SpringCloud之SpringCloud简介

    深入学习SpringCloud之SpringCloud简介

    Spring Cloud是一个一站式的开发分布式系统的框架,为开发者提供了一系列的构建分布式系统的工具集,本文给大家介绍springcloud的相关知识,感兴趣的朋友跟随一起看看吧
    2021-04-04
  • Eclipse搭建spring开发环境图文教程(推荐)

    Eclipse搭建spring开发环境图文教程(推荐)

    下面小编就为大家带来一篇Eclipse搭建spring开发环境图文教程(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • jdk21环境配置详细步骤记录

    jdk21环境配置详细步骤记录

    JDK是整个Java开发的核心,它包含了Java的运行环境和Java工具,这篇文章主要给大家介绍了关于jdk21环境配置的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Java使用Scanner类获取用户输入实例详解

    Java使用Scanner类获取用户输入实例详解

    在本篇文章里小编给大家整理了关于Java使用Scanner类获取用户输入实例内容,有兴趣的朋友们学习下。
    2019-11-11
  • SpringBoot基于Sentinel在服务上实现接口限流

    SpringBoot基于Sentinel在服务上实现接口限流

    这篇文章主要介绍了SpringBoot基于Sentinel在服务上实现接口限流,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java基础之文件概述

    Java基础之文件概述

    这篇文章主要介绍了Java基础之文件概述,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有一定的帮助,需要的朋友可以参考下
    2021-05-05
  • maven解决依赖冲突的三种解决方法

    maven解决依赖冲突的三种解决方法

    依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突,本文主要介绍了maven解决依赖冲突的三种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Jmeter结构体系及运行原理顺序解析

    Jmeter结构体系及运行原理顺序解析

    这篇文章主要介绍了Jmeter结构体系及运行原理顺序解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • idea Gradle 控制台中文乱码的解决

    idea Gradle 控制台中文乱码的解决

    通过IDEA执行gradle的任务时,在终端的输出出现中文乱码,本文主要介绍了idea Gradle 控制台中文乱码的解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论