@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
如果我们有一个 不是 @Id 的 UUID
,我们可以添加 @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
向 ServerConfig 注册 IdGenerator。
请注意,如果你正在使用类路径扫描来查找实体 Bean,那么它还将自动查找 IdGenerator 的实现并自动注册它们,因此在这种情况下,你不需要使用 ServerConfig 手动注册 IdGenerator。
3. @GeneratedValue
然后,我们可以通过使用 @GeneratedValue
(生成器是我们自定义 IdGenerator 的名称)告诉 Ebean 使用我们的自定义 IdGenerator。
@Id @GeneratedValue(generator = "shortUid")
String id;
没有延迟加载
请注意,@Id
属性从不调用延迟加载。
数据库平台
所有受支持的数据库都使用 Identity
或 Sequences
(或允许两者),并且 Ebean 将根据数据库平台选择适当的 Id 生成策略。
数据库 | 策略 |
---|---|
H2 | Identity(也支持序列) |
Postgres | Identity(作为序列,也支持序列) |
MySql | 标识 |
Oracle | Sequences(也支持 Identity) |
DB2 | Identity(也支持序列) |
SQL Server | 标识 |
SQLite | 标识 |
SqlAnywhere | 标识 |