概述

可草稿功能使用第二组表来单独保存对象图的“草稿”版本,与“实时”版本分开。通常,草稿对象在发布之前会进行编辑并通过审批流程。

要实现此功能,所有 @Draftable 和 @DraftElement bean 都具有第二个草稿表,该表与实时表非常相似,但通常会有其他列来支持发布的审批工作流。

发布是一项功能,它从草稿表中获取基础行并将其复制到匹配的实时表中。通过这种方式,应用程序可以轻松维护实体的“草稿”版本和“实时”版本。

映射


实体映射

@Draftable

@Draftable 是一个注释,用于支持可草稿功能的实体 bean。

将 @Draftable 注释用于“顶级”(或根级)实体 bean,将 @DraftableElement 用于相关子实体 bean,这些子实体 bean 被视为同一图的一部分。

发布 @Draftable bean 将发布“顶级”@Draftable 实体 bean 以及其任何相关的子 @DraftableElement bean。

@DraftableElement

@DraftableElement 是一个注释,用于实体 bean,这些实体 bean 是可草稿对象图的一部分,但不是“顶级”bean。publish() 和 draftRestore() 函数对可草稿 bean 及其所有关联的 draftableElement bean 作为一个单元进行操作(作为一个单元发布/恢复)。


属性映射

@DraftOnly

@DraftOnly 是一个注释,用于仅存在于草稿表中的属性 - 这些属性不存在于关联的实时表中。例如,支持审批工作流的草稿上的注释属性(工作流状态、发布的时间戳等)。

@DraftDirty

@DraftDirty 是一个注释,可以用于 @Draftable 实体 bean 的布尔属性。此属性仅存在于草稿表中,其值在保存草稿 bean 时自动设置为 true,在发布草稿 bean 时自动设置为 false。此属性预计用于标识(查询)应发布的草稿 bean。

目前对 @DraftableElement 的更改不会设置“所有者”@Draftable bean 上的脏标志,而如果需要,则在这种情况下需要手动完成此操作。

@DraftReset

@DraftReset 是一个注释,可以放在 @Draftable 实体 bean 的属性上。此属性的值在草稿 bean 发布后自动设置为 null。例如,该属性可以包含与审批工作流相关的注释或时间戳值(并且在 bean 发布后,这些值在草稿 bean 上“重置”为 null)。

查询为草稿

普通查询从“实时”表构建对象图。您可以指定查询以运行 asDraft(),然后它将使用草稿表构建对象图。这可用于预览对象图的当前编辑状态。

// Get the 'draft' object graph
Document documentDraft =
    Ebean.find(Document.class)
      .setId(docId)
      .asDraft()
      .findOne();


// Get the 'draft' documents
List<Document> draftDocuments =
    Ebean.find(Document.class)
      .where()
        .eq("dirty", true)
        .ge("whenPublish", now)
      .asDraft()
      .findList();

注意:asDraft 查询状态传播到任何延迟加载或查询联接。

注意:任何 asDraft 查询都不会使用 L2 缓存(只有针对实时 bean 的查询才能使用 L2 缓存)。

发布

Publish 是一个函数,它从草稿对象图中获取值并将其应用到匹配的实时对象图。发布函数从顶级 @Draftable 实体 bean 级联到任何相关的 @DraftableElement 实体 bean。

@OneToMany

与 @DraftableElement 的 @OneToMany 关系实际上会自动启用保存和删除级联。级联保存/删除在内部用于发布对象图。

@ManyToMany

与 @Draftable bean 的 @ManyToMany 关系实际上会自动启用保存和删除级联以维护关系。

Database database = DB.getDefault();

// publish a single bean (from draft to live)
// returning the 'live' bean
Document liveDoc = database.publish(Document.class, docId);


// publish using a query
Query<Link> pubQuery = database.find(Link.class)
  .where().idIn(ids)
  .order().asc("id");

// publish returning the resulting 'live' beans
List<Link> pubList = database.publish(pubQuery);

草稿还原

DraftRestore 是一个函数,它从实时对象图中获取值并将其重新应用到匹配的草稿对象图。您可以将其视为 publish() 的反向操作。

Database database = DB.getDefault();

// Restore a single draft bean
database.draftRestore(Document.class, docId);


Query<Document> restoreQuery = database.find(Document.class)
  .where().idIn(ids)
  .order().asc("id");

// Restore all the beans matching a query
database.draftRestore(restoreQuery);

示例应用程序

示例应用程序可在 example-draftable 获得。

L2 缓存

只有实时 bean 和查询才能使用 L2 缓存。同样,只有实时 bean 的保存/删除才会使 L2 缓存的部分无效。对草稿 bean 的所有查询都不会使用 L2 缓存,而草稿 bean 的保存/删除不会使 L2 缓存的任何部分无效。