102
@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抽象类?有什么用?

4

4 回答 4

148

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

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

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

@GeneratedValue(strategy = GenerationType.IDENTITY)

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

1.在数据库中定义Sequence

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

create sequence oracle_seq;

2.参考数据库序列

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

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

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

3.在Java中使用序列

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

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

generator字段是指您要使用的序列生成器。请注意,它不是 DB 中的真实序列名称,而是您nameSequenceGenerator.

4.完成

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

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

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

于 2013-12-16T07:20:08.640 回答
27

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

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

指示持久性提供程序必须使用数据库标识列为实体分配主键。

还有其他策略,你可以在这里看到更多。

于 2013-12-16T04:51:57.147 回答
19
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

于 2018-11-23T12:27:03.733 回答
0

我们为什么要使用这个注解?

  • 首先我想提醒大家,注解,例如@Id,正在为持久层提供元数据(我将假设休眠)。这个元数据很可能存储在.class文件中(但不存储在数据库中)并且是用于告诉hibernate如何识别、解释和管理实体。那么,你为什么要使用注解呢?为您的持久层提供有关如何管理实体的正确信息。

为什么要使用@Id 注解?

  • @Id注解是使用 JPA 创建实体时所需的两个必需注解之一。另一个是@Entity@Id为我们做了两件事:

    1)表示该字段在映射到数据库表时将是该类的唯一标识符

    2)的存在@Id让持久层知道该类中的所有其他字段都将映射到数据库行

为什么使用@GeneratedValue?

  • 通过使用标记@Id字段,@GeneratedValue我们现在启用id generation. 这意味着持久层将为我们生成一个 Id 值并处理自动递增。我们的应用程序可以选择 4 代策略中的 1 个:

    1) 自动

    2) 表

    3) 序列

    4) 身份

  • 如果未指定策略,则假定为 AUTO

strategy = GenerationType.IDENTITY 实际上在做什么?

  • 当我们指定生成策略时,GenerationType.IDENTITY我们告诉持久性提供程序(休眠)让数据库处理 id 的自动递增。如果您使用 postgres 作为基础数据库并将策略指定为IDENTITY,hibernate 将执行以下操作:
create table users (
       id  bigserial not null,
        primary key (id)
    )

  • 请注意,他们的 id 类型是bigserial,什么是 bigserial?根据 postgres文档bigserial is a large autoincrementing integer.

结论

  • 通过指定:
@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

  • 您已经告诉底层持久层使用 id 字段作为数据库中的唯一标识符。还告诉持久层让数据库处理 id 的自动递增GenerationType.IDENTITY
于 2022-02-12T21:12:27.437 回答