注释@Id 和@GeneratedValue(strategy = GenerationType.IDENTITY) 有啥用?为啥世代类型是身份?

Posted

技术标签:

【中文标题】注释@Id 和@GeneratedValue(strategy = GenerationType.IDENTITY) 有啥用?为啥世代类型是身份?【英文标题】:what is the use of annotations @Id and @GeneratedValue(strategy = GenerationType.IDENTITY)? Why the generationtype is identity?注释@Id 和@GeneratedValue(strategy = GenerationType.IDENTITY) 有什么用?为什么世代类型是身份? 【发布时间】:2014-01-03 09:56:02 【问题描述】:
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY)

我们为什么要使用这个注解? 我需要知道这是否会自动增加我的表 id 值。 (GenerationType.IDENTITY) 是否还有其他类型在我们使用此注解时实际发生的情况

public class Author extends Domain

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id") 
    private Integer id;

    @Basic(optional = false)
    @Column(name = "name") 
    private String name;

    @Column(name = "address") 
    private String address; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "authorId")
    private List<Book>
    bookList;

    public Author()
     
        setServiceClassName("wawo.tutorial.service.admin.AuthorService");
    

*是否需要扩展Domain抽象类?有什么用?

【问题讨论】:

docs.oracle.com/javaee/5/api/javax/persistence/… 【参考方案1】:

首先,使用注解作为我们的配置方法只是一种方便的方法,而不是应付无穷无尽的XML配置文件。

@Id注解继承自javax.persistence.Id,表示下面的成员字段是当前实体的主键。因此,您的 Hibernate 和 spring 框架以及您可以基于此注释做一些 reflect 工作。详情请查看javadoc for Id

@GeneratedValue注解是配置指定列(字段)的递增方式。比如使用mysql时,可以在table的定义中指定auto_increment使其自增,然后使用

@GeneratedValue(strategy = GenerationType.IDENTITY)

在Java 代码中表示您也承认使用此数据库服务器端策略。此外,您可以更改此注释中的值以适应不同的要求。

1。在数据库中定义序列

例如,Oracle 必须使用sequence 作为增量方法,假设我们在 Oracle 中创建了一个序列:

create sequence oracle_seq;

2。参考数据库序列

现在我们已经有了数据库中的序列,但是我们需要建立Java和DB之间的关系,使用@SequenceGenerator

@SequenceGenerator(name="seq",sequenceName="oracle_seq")

sequenceName 是 Oracle 中序列的真实名称,name 是您在 Java 中要称呼它的名称。如果与name不同,则需要指定sequenceName,否则使用name。我通常会忽略sequenceName 以节省我的时间。

3。在 Java 中使用序列

最后,是时候在 Java 中使用这个序列了。只需添加@GeneratedValue

@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")

generator 字段是指您要使用的序列生成器。注意它不是DB中真正的序列名称,而是您在SequenceGeneratorname字段中指定的名称。

4。完成

所以完整的版本应该是这样的:

public class MyTable

    @Id
    @SequenceGenerator(name="seq",sequenceName="oracle_seq")        
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq")               
    private Integer pid;

现在开始使用这些注释来简化您的 JavaWeb 开发。

【讨论】:

Oracle 11.2 注解 SequenceGenerator 的正确语法是 @SequenceGenerator(name="seq", sequenceName="ORACLE_SEQ", allocationSize=1)。否则,如果没有 allocationSize 参数,它会产生非常奇怪的结果(在我的情况下为负)。 @hariprasad 在我的情况下,如果我不设置它,增量为 10。但这仍然是一个可选参数。 我的一个朋友说@Id 用于唯一标识。如果您将遵循代码优先方法,那么它将是主键,否则会有所不同。你能解释一下上面说的那句话吗? @PSatishPatro 正确,ID 当然是唯一记录。但是我们在表定义中总会有这样的东西,即使对于 NoSQL @SatishPatro 根据Javadoc,它用于主键【参考方案2】:

在对象关系映射上下文中,每个对象都需要有一个唯一标识符。您使用@Id 注解来指定实体的主键。

@GeneratedValue 注解用于指定应如何生成主键。在您的示例中,您使用的是Identity 策略

表示持久化提供者必须为 使用数据库标识列的实体。

还有其他攻略,可以看更多here。

【讨论】:

“表示持久化提供者必须使用数据库标识列为实体分配主键。”你能解释一下吗 @404 数据库用于生成主键的一种策略是保留一个带有列 (YMMV) 的表,其中只存储分配的 id。当必须输入新行时,将生成并使用原来不在表中的新 id。 所以是 id 自动递增吗? @404 我认为这取决于数据库。使用 MySQL 时看起来就是这样,但使用其他数据库时可能会有所不同。【参考方案3】:
Simply, @Id: This annotation specifies the primary key of the entity. 

@GeneratedValue: This annotation is used to specify the primary key generation strategy to use. i.e Instructs database to generate a value for this field automatically. If the strategy is not specified by default AUTO will be used. 

GenerationType enum defines four strategies: 
1. Generation Type . TABLE, 
2. Generation Type. SEQUENCE,
3. Generation Type. IDENTITY   
4. Generation Type. AUTO

GenerationType.SEQUENCE

With this strategy, underlying persistence provider must use a database sequence to get the next unique primary key for the entities. 

GenerationType.TABLE

With this strategy, underlying persistence provider must use a database table to generate/keep the next unique primary key for the entities. 

GenerationType.IDENTITY
This GenerationType indicates that the persistence provider must assign primary keys for the entity using a database identity column. IDENTITY column is typically used in SQL Server. This special type column is populated internally by the table itself without using a separate sequence. If underlying database doesn't support IDENTITY column or some similar variant then the persistence provider can choose an alternative appropriate strategy. In this examples we are using H2 database which doesn't support IDENTITY column.

GenerationType.AUTO
This GenerationType indicates that the persistence provider should automatically pick an appropriate strategy for the particular database. This is the default GenerationType, i.e. if we just use @GeneratedValue annotation then this value of GenerationType will be used. 

参考:-https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/jpa-primary-key.html

【讨论】:

以上是关于注释@Id 和@GeneratedValue(strategy = GenerationType.IDENTITY) 有啥用?为啥世代类型是身份?的主要内容,如果未能解决你的问题,请参考以下文章

一对多 JPA 注释不会删除孤儿

JPA注释/持久类

Hibernate 注释放置问题

如何使用 @ID 和 @GeneratedValue 从 Hibernate + JPA 中的序列中获取 Oracle 生成的值

@GeneratedValue

JPA 何时设置 @GeneratedValue @Id