69

Doctrine 文档@GeneratedValue中,他们提到注释存在一些不同的策略:

  • AUTO
  • SEQUENCE
  • TABLE
  • IDENTITY
  • UUID
  • CUSTOM
  • NONE

有人可以解释一下所有这些策略之间的区别吗?

4

3 回答 3

105

检查最新的学说文档

这是一个摘要:可能的生成策略列表:

AUTO(默认):告诉 Doctrine 选择使用的数据库平台首选的策略。首选策略是IDENTITYMySQL、SQLite 和 MsSQL 以及SEQUENCEOracle 和 PostgreSQL。这种策略提供了完全的可移植性。

SEQUENCE:告诉 Doctrine 使用数据库序列进行ID生成。此策略当前不提供完全可移植性。Oracle、PostgreSql 和 SQL Anywhere 支持序列。

IDENTITY:告诉 Doctrine 在数据库中使用特殊的标识列,在插入行时生成一个值。此策略目前不提供完全可移植性,并受以下平台支持:

  • MySQL/SQLite/SQL Anywhere =>AUTO_INCREMENT
  • 微软 SQL =>IDENTITY
  • PostgreSQL =>SERIAL

TABLE:告诉 Doctrine 使用单独的表进行ID生成。这种策略提供了完全的可移植性。该策略尚未实施!

NONE:告诉 Doctrine 标识符是由您的代码分配并因此生成的。必须在将新实体传递给 EntityManager#persist 之前进行分配。NONE与完全放弃是一样的@GeneratedValue

从 2.3 版开始:

UUID:告诉 Doctrine 使用内置的通用唯一标识符生成器。这种策略提供了完全的可移植性。

于 2012-12-25T08:42:07.950 回答
6

当然接受的答案是正确的,但它需要一个小的更新,如下所示:

根据文档的注释部分:

此注解是可选的,仅在与@Id 结合使用时才有意义。如果未使用 @Id 指定此注释,则默认使用NONE策略。

策略属性是可选的。

根据文档的基本映射部分:

SEQUENCE: 告诉 Doctrine 使用数据库序列来生成 ID。此策略当前不提供完全可移植性。OraclePostgreSqlSQL Anywhere支持序列。

IDENTITY:告诉 Doctrine 使用数据库中的特殊标识列,在插入行时生成一个值。此策略目前不提供完全可移植性,并受以下平台支持:

  • MySQL / SQLite / SQL Anywhere (AUTO_INCREMENT)
  • MSSQL(身份)
  • PostgreSQL(串行)。

否决票

关于某人给出的反对意见,应该注意已添加SQL Anywhere并且接受的答案需要进行小更新

于 2016-10-22T19:55:27.077 回答
2

从程序员的角度来看,它们都达到了相同的结果:即为主键字段提供一个 UNIQUE 值。严格来说,还需要满足两个进一步的条件,即:密钥也必须是强制性的,而不是 null

唯一的区别在于提供主键值的内部实现。此外,还需要考虑性能和数据库兼容性因素。不同的数据库支持不同的策略。

最容易理解的是SEQUENCE,这通常也是产生最佳性能优势的一种。在这里,数据库维护一个内部序列,其 nextval 由一个额外的 SQL 调用访问,如下所示:

SELECT nextval ('hibernate_sequence')

在插入每个新行期间分配下一个值。尽管有额外的 SQL 调用,但对性能的影响可以忽略不计。使用SEQUENCE,可以使用@SequenceGenerator注释指定初始值(默认为 1)和分配大小(默认 = 50):

@SequenceGenerator(name="seq", initialValue=1, allocationSize=100)

IDENTITY策略依赖于数据库通过在表中维护一个附加列来生成主键,每当插入新行时,该列的下一个值就会自动生成。每个类型层次结构都需要一个单独的标识生成器。

TABLE策略依赖于一个单独的表来存储和更新每个新行插入的序列。它使用悲观锁来维护序列,因此是所有这些选项中最慢的策略。可能值得注意的是,@TableGenerator可以使用注解来指定此策略的生成器名称、表名称和模式:

@TableGenerator(name="book_generator", table="id_generator", schema="bookstore")

使用 UUID 选项,持久性提供程序(例如 Hibernate)生成一个通用唯一 ID,其形式为:'8dd5f315-9788-4d00-87bb-10eed9eff566'。要选择此选项,只需在数据类型为 UUID 的字段声明上方应用 @GeneratedValue 注释即可;例如:

@Entity
public class UUIDDemo {

    @Id
    @GeneratedValue
    private UUID uuid;

    // ...
}

最后,该AUTO策略是默认策略,使用此选项,持久性提供程序将为正在使用的数据库选择最佳策略。

于 2018-12-28T04:08:54.173 回答