6.5. 查询审计信息


6.5.1. 通过队列检索审计信息

Hibernate Envers 提供通过查询检索审计信息的功能。

注意

许多情况下,对审计数据的查询比 实时数据 的相应查询要慢得多,因为它们涉及关联的子选择。

通过给定修订版本查询类实体

此查询的入口点为:

AuditQuery query = getAuditReader()
    .createQuery()
    .forEntitiesAtRevision(MyEntity.class, revisionNumber);
Copy to Clipboard Toggle word wrap

然后,可以使用 AuditEntity 工厂类别指定限制。以下查询仅选择 name 属性等于 John 的实体:

query.add(AuditEntity.property("name").eq("John"));
Copy to Clipboard Toggle word wrap

以下查询只选择与给定实体相关的实体:

query.add(AuditEntity.property("address").eq(relatedEntityInstance));
// or
query.add(AuditEntity.relatedId("address").eq(relatedEntityId));
Copy to Clipboard Toggle word wrap

然后可以订购、限制结果,并且设置聚合和预测(分组除外)。以下示例是一个完整的查询。

List personsAtAddress = getAuditReader().createQuery()
    .forEntitiesAtRevision(Person.class, 12)
    .addOrder(AuditEntity.property("surname").desc())
    .add(AuditEntity.relatedId("address").eq(addressId))
    .setFirstResult(4)
    .setMaxResults(2)
    .getResultList();
Copy to Clipboard Toggle word wrap

查询修订,其中给定类的实体更改

此查询的入口点为:

AuditQuery query = getAuditReader().createQuery()
    .forRevisionsOfEntity(MyEntity.class, false, true);
Copy to Clipboard Toggle word wrap

限制可以添加到此查询中,方式与上例相同。这个查询还有其它可能:

AuditEntity.revisionNumber()
指定修改审计实体的修订版本号的限制、预测和顺序。
AuditEntity.revisionProperty(propertyName)
指定修订实体属性的限制、预测和订单,对应于修改审计实体的修订版本。
AuditEntity.revisionType()
提供对修订版本类型的访问(ADD、MOD、DEL)。

然后可以根据需要调整查询结果。以下查询选择 MyEntity 类的实体的最小修订号,其中的 entity Id ID 在修订号 42 后更改:

Number revision = (Number) getAuditReader().createQuery()
    .forRevisionsOfEntity(MyEntity.class, false, true)
    .setProjection(AuditEntity.revisionNumber().min())
    .add(AuditEntity.id().eq(entityId))
    .add(AuditEntity.revisionNumber().gt(42))
    .getSingleResult();
Copy to Clipboard Toggle word wrap

对修订的查询也可以最小化/最大化属性。以下查询选择给定实体的 actualDate 值大于给定值的修订版本,但尽量小:

Number revision = (Number) getAuditReader().createQuery()
    .forRevisionsOfEntity(MyEntity.class, false, true)
    // We are only interested in the first revision
    .setProjection(AuditEntity.revisionNumber().min())
    .add(AuditEntity.property("actualDate").minimize()
        .add(AuditEntity.property("actualDate").ge(givenDate))
        .add(AuditEntity.id().eq(givenEntityId)))
    .getSingleResult();
Copy to Clipboard Toggle word wrap

mini ()和 max()方法 返回一个条件,可以向其中添加约束,但具有最大/最小 属性的实体必须满足此条件。

创建查询时传递两个布尔值参数:

selectEntitiesOnly

这个参数只有在未设置显式投射时才有效。
如果为 true,则查询的结果将是满足指定限制修订版本时更改的实体列表。
为 false,则结果将是三个元素数组的列表。第一个元素是更改后的实体实例。第二个是包含修订数据的实体。如果不使用自定义实体,这将是 DefaultRevisionEntity 实例。第三个元素数组将是修订的类型(ADD、MOD、DEL)。
selectDeletedEntities
此参数指定是否必须将删除实体的修订包含在结果中。如果为 true,实体将具有修订类型 DEL,除 id 外的所有字段都将值为 null

查询修改后属性的实体的修订

以下查询将返回 MyEntity 及给定 ID 的所有修订,其中的 actualDate 属性已更改。

AuditQuery query = getAuditReader().createQuery()
  .forRevisionsOfEntity(MyEntity.class, false, true)
  .add(AuditEntity.id().eq(id));
  .add(AuditEntity.property("actualDate").hasChanged())
Copy to Clipboard Toggle word wrap

hasChanged 条件可以和附加标准组合。以下查询将在生成 revisionNumber 时为 MyEntity 返回一个横向片段。它仅限于修改 prop1 但不修改 prop 2 的修订版本。

AuditQuery query = getAuditReader().createQuery()
  .forEntitiesAtRevision(MyEntity.class, revisionNumber)
  .add(AuditEntity.property("prop1").hasChanged())
  .add(AuditEntity.property("prop2").hasNotChanged());
Copy to Clipboard Toggle word wrap

结果集还包含数字低于 revisionNumber 的修订版本。这意味着,这个查询无法读取为"通过 prop1 修改和 prop 2 不更改的 revisionNumber 中所有 MyEntities 更改"。

以下查询显示如何使用 forEntitiesModifiedAtRevision 查询返回这个结果:

AuditQuery query = getAuditReader().createQuery()
  .forEntitiesModifiedAtRevision(MyEntity.class, revisionNumber)
  .add(AuditEntity.property("prop1").hasChanged())
  .add(AuditEntity.property("prop2").hasNotChanged());
Copy to Clipboard Toggle word wrap

在给定修订版本中修改查询实体

以下示例显示了给定修订中修改的实体的基本查询。它允许检索指定修订中更改的实体名称和对应 Java 类:

Set<Pair<String, Class>> modifiedEntityTypes = getAuditReader()
    .getCrossTypeRevisionChangesReader().findEntityTypes(revisionNumber);
Copy to Clipboard Toggle word wrap

还可以从 org.hibernate.envers.CrossTypeRevisionChangesReader 访问许多其他查询:

list<Object> findEntities(Number)
返回给定修订中更改(添加、更新和删除)的所有审计实体的快照。执行 n+1 SQL 查询,其中 n 是指定修订版本中修改的多个不同实体类。
List<Object> findEntities(Number, RevisionType)
返回给定修订版本中更改(添加、更新或删除)的所有审计实体的快照,并按照修改类型过滤。执行 n+1 SQL 查询,其中 n 是指定修订版本中修改的多个不同实体类。Map<RevisionType, List<Object>>
findEntitiesGroupByRevisionType(Number)
返回包含由修改操作分组的实体快照列表的映射,如添加、更新或删除。执行 3n+1 SQL 查询,其中 n 是指定修订版本中修改的多个不同实体类。
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat