11.7.6. クエリ

11.7.6.1. 監査情報の読み出し

概要

Hibernate Envers はクエリより監査情報を読み出しする機能を提供します。このトピックではクエリの例を取り上げます。

注記

監査されたデータのクエリは相関サブセレクトが関与するため、多くの場合で live データの対応するクエリよりも大幅に処理が遅くなります。

例11.33 特定のリビジョンでクラスのエンティティーをクエリする

このようなクエリのエントリーポイントは次の通りです。
AuditQuery query = getAuditReader()
    .createQuery()
    .forEntitiesAtRevision(MyEntity.class, revisionNumber);
AuditEntity ファクトリクラスを使用して制約を指定することができます。以下のクエリは、name プロパティーが John と同等である場合のみエンティティーを選択します。
query.add(AuditEntity.property("name").eq("John"));
以下のクエリは特定のエンティティーと関連するエンティティーのみを選択します。
query.add(AuditEntity.property("address").eq(relatedEntityInstance));
// or
query.add(AuditEntity.relatedId("address").eq(relatedEntityId));
結果を順序付けや制限付けしたり、凝集 (aggregations) および射影 (projections) のセット (グループ化を除く) を持つことが可能です。以下はフルクエリの例になります。
List personsAtAddress = getAuditReader().createQuery()
    .forEntitiesAtRevision(Person.class, 12)
    .addOrder(AuditEntity.property("surname").desc())
    .add(AuditEntity.relatedId("address").eq(addressId))
    .setFirstResult(4)
    .setMaxResults(2)
    .getResultList();

例11.34 特定クラスのエンティティーが変更された場合のクエリリビジョン

このようなクエリのエントリーポイントは次の通りです。
AuditQuery query = getAuditReader().createQuery()
    .forRevisionsOfEntity(MyEntity.class, false, true);
前の例と同様に、このクエリへ制約を追加することが可能です。このクエリに以下を追加することも可能です。
AuditEntity.revisionNumber()
監査されたエンティティーが修正されたリビジョン番号の制約や射影、順序付けを指定します。
AuditEntity.revisionProperty(propertyName)
監査されたエンティティーが修正されたリビジョンに対応するリビジョンエンティティーのプロパティーの制約や射影、順序付けを指定します。
AuditEntity.revisionType()
リビジョンのタイプ (ADD、MOD、DEL) へのアクセスを提供します。
クエリ結果を必要に応じて調整することが可能です。次のクエリは、リビジョン番号 42 の後に entityId ID を持つ MyEntity クラスのエンティティーが変更された最小のリビジョン番号を選択します。
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();
リビジョンのクエリはプロパティーを最小化および最大化することも可能です。次のクエリは、特定エンティティーの 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();
minimize() および maximize() メソッドは制約を追加できる基準を返します。最大化または最小化されたプロパティーを持つエンティティーはこの基準を満たさなければなりません。
クエリ作成時に渡されるブール変数パラメーターは 2 つあります。
selectEntitiesOnly
このパラメーターは明示的な射影が設定されていない場合のみ有効です。
true の場合、クエリの結果は指定された制約を満たすリビジョンで変更されたエンティティーの一覧になります。
false の場合、結果は 3 つの要素アレイの一覧になります。最初の要素は変更されたエンティティーインスタンスになります。2 番目の要素はリビジョンデータが含まれるエンティティーになります。カスタムエンティティーが使用されていない場合は DefaultRevisionEntity のインスタンスになります。3 つ目の要素アレイはリビジョンのタイプ (ADD、MOD、DEL) になります。
selectDeletedEntities
このパラメーターは、エンティティーが削除されたリビジョンが結果に含まれなければならない場合に指定されます。true の場合、エンティティーのリビジョンタイプが DEL になり、id 以外のすべてのフィールドの値が null になります。

例11.35 特定のプロパティーを修正したエンティティーのクエリリビジョン

下記のクエリは、actualDate プロパティーが変更された、指定の ID を持つ MyEntity のすべてのリビジョンを返します。
AuditQuery query = getAuditReader().createQuery()
  .forRevisionsOfEntity(MyEntity.class, false, true)
  .add(AuditEntity.id().eq(id));
  .add(AuditEntity.property("actualDate").hasChanged())
hasChanged 条件を他の基準と組み合わせることができます。次のクエリは、revisionNumber 生成時に MyEntity の水平スライスを返します。これは、prop1 は修正され、prop2 は修正されなかったリビジョンに限定されます。
AuditQuery query = getAuditReader().createQuery()
  .forEntitiesAtRevision(MyEntity.class, revisionNumber)
  .add(AuditEntity.property("prop1").hasChanged())
  .add(AuditEntity.property("prop2").hasNotChanged());
結果セットには revisionNumber よりも小さい番号のリビジョンも含まれます。これは、このクエリが「prop1 は修正され、prop2 はそのままの revisionNumber で変更された MyEntities をすべて返す」とは読み取られないことを意味します。
次のクエリは forEntitiesModifiedAtRevision を使用してこの結果がどのように返されるか表しています。
AuditQuery query = getAuditReader().createQuery()
  .forEntitiesModifiedAtRevision(MyEntity.class, revisionNumber)
  .add(AuditEntity.property("prop1").hasChanged())
  .add(AuditEntity.property("prop2").hasNotChanged());

例11.36 特定のリビジョンで修正されたクエリエンティティー

次の例は、特定のリビジョンで変更されたエンティティーに対する基本的なクエリになります。読み出される特定のリビジョンで、エンティティー名と対応する Java クラスを変更できます。
Set<Pair<String, Class>> modifiedEntityTypes = getAuditReader()
    .getCrossTypeRevisionChangesReader().findEntityTypes(revisionNumber);
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 は指定のリビジョン内で変更された異なるエンティティークラスの数になります)。

このページには機械翻訳が使用されている場合があります (詳細はこちら)。