@Id

将属性标记为 @Id 属性。

@Entity
public class Contact {

  @Id
  long id;

  ...
}

@GeneratedValue

当我们使用 @Id 为属性添加注释时,如果类型是数字类型或 UUID 类型,Ebean 将自动分配一个合适的 Id 生成器

也就是说,使用 Ebean 时,添加 @GeneratedValue 注释实际上是多余的。

@Id
long id;

// ... is effectively the same as

@Id @GeneratedValue
long id;

@Identity

当我们希望使用 起始值缓存值默认生成 | 始终生成 选项来指定数据库标识或序列时,Ebean 还提供了一个 @Identity 注释。

我们希望使用它来专门设置 缓存 选项,当关联表预计会获得大量插入时,我们希望允许支持它的数据库具有高于正常水平的 id 缓存,以减少围绕生成 id 值/序列的争用。Postgres、Oracle 和 NuoDB 都支持设置标识缓存选项。id 值缓存较大的缺点是,如果数据库重新启动,id 值中可能会出现较大的间隙。

@Id @Identity(start=10000, cache=500)
long id;

我们还可以在类上指定 @Identity - 通常是在从 MappedSuperclass 继承 id 属性时。

@Entity
@Identity(start=10000, cache=500)
public class Contact {

  @Id
  long id;

  ...
}

UUID

如果 @Id 类型是 UUID,则 Ebean 将自动为该属性分配一个合适的 Id 生成器。

// an appropriate UUID based Id generator
// is automatically assigned
@Id
UUID id;

UUID 和 @GeneratedValue

如果我们有一个 不是 @IdUUID,我们可以添加 @GeneratedValue,然后 Ebean 将为其分配一个合适的 UUID 生成器。

/** The Id property using DB Identity or Sequence */
@Id @GeneratedValue
private long id;

/** Alternate unique UUID property */
@GeneratedValue @Column(unique = true)
private UUID uid;

字符串

如果 @Id 类型是 String,则 Ebean 假设 id 值由应用程序提供。在这种情况下,不会为 Id 属性分配 Id 生成器。

@Id
String code;

一个示例是将 ISO 国家代码用作国家/地区的主键。

没有 @Id 属性的实体

我们可以对没有任何 @Id 属性的实体 Bean 进行建模。这种情况有两种:对视图进行建模和对表示事件日志或类似内容的“仅插入”表进行建模时。

视图

当实体 Bean 被建模为 @View 时,视图通常没有与主键等效的列。

示例 - 基于具有 @Id 属性的视图的实体
@Entity
@View(name = "machine_stats")
public class MachineStats {

  @ManyToOne
  Machine machine;

  LocalDate date;

  @Sum  // equivalent to @Aggregation("sum(totalKms)")
  long totalKms;

  @Sum
  long hours;

  @Max
  BigDecimal rate;

  @Aggregation("sum(cost)")
  BigDecimal totalCost;

  @Aggregation("max(totalKms)")
  BigDecimal maxKms;

没有主键的表

在对“仅追加”表进行建模时,我们不需要主键,那么我们可能希望没有 @Id 属性和没有实际主键。当我们希望避免主键索引的开销(应用程序永远不需要或使用)时,我们可能希望这样做。

对于 Postgres,我们通常会通过 @DbPartition 对这种类型的“仅追加”事件类型表使用表分区。

示例 - 仅追加表,没有主键/没有 @Id 属性
/**
 * Append only table with no Id property, no primary key (no primary key index).
 */
@DbPartition(mode = DAY, property = "eventTime")
@Entity
@Table(name = "machine_log")
public class MachineLog {

  @Index
  @NotNull
  protected Instant eventTime;

  @DbForeignKey(noConstraint = true)
  @ManyToOne(optional = false)
  protected Machine machine;

  ...

自定义 Id 生成器

支持注册和使用自定义 Id 生成器。

1. 实现 io.ebean.config.IdGenerator

public class ModUuidGenerator implements IdGenerator {

  @Override
  public Object nextValue() {
    return ModUUID.newShortId();
  }

  @Override
  public String getName() {
    return "shortUid";
  }
}

2. 使用 ServerConfig 注册

我们通过使用 addClass()add(IdGenerator idGenerator)setIdGenerators(List idGenerators) 向 ServerConfig 注册 IdGenerator。

请注意,如果你正在使用类路径扫描来查找实体 Bean,那么它还将自动查找 IdGenerator 的实现并自动注册它们,因此在这种情况下,你不需要使用 ServerConfig 手动注册 IdGenerator。

3. @GeneratedValue

然后,我们可以通过使用 @GeneratedValue(生成器是我们自定义 IdGenerator 的名称)告诉 Ebean 使用我们的自定义 IdGenerator。

@Id @GeneratedValue(generator = "shortUid")
String id;

没有延迟加载

请注意,@Id 属性从不调用延迟加载。

数据库平台

所有受支持的数据库都使用 IdentitySequences(或允许两者),并且 Ebean 将根据数据库平台选择适当的 Id 生成策略。

数据库策略
H2Identity(也支持序列)
PostgresIdentity(作为序列,也支持序列)
MySql标识
OracleSequences(也支持 Identity)
DB2Identity(也支持序列)
SQL Server标识
SQLite标识
SqlAnywhere标识