首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用spring data envers查找实体的所有修订?

如何使用spring data envers查找实体的所有修订?
EN

Stack Overflow用户
提问于 2016-03-15 18:17:14
回答 3查看 9.5K关注 0票数 10

我在spring boot应用程序中使用了spring-data-envers。我可以成功地记录对我的实体的审计。

现在,我需要在UI中向用户显示审核后的数据。就像将有一个搜索表单,用户可以选择持续时间和他想要查看审计日志的实体。

由string-data-envers提供的RevisionRepository只有三种方法,如下所示。

代码语言:javascript
复制
@NoRepositoryBean
public interface RevisionRepository<T, ID extends Serializable, N extends Number & Comparable<N>> {

    /**
     * Returns the revision of the entity it was last changed in.
     * 
     * @param id must not be {@literal null}.
     * @return
     */
    Revision<N, T> findLastChangeRevision(ID id);

    /**
     * Returns all {@link Revisions} of an entity with the given id.
     * 
     * @param id must not be {@literal null}.
     * @return
     */
    Revisions<N, T> findRevisions(ID id);

    /**
     * Returns a {@link Page} of revisions for the entity with the given id.
     * 
     * @param id must not be {@literal null}.
     * @param pageable
     * @return
     */
    Page<Revision<N, T>> findRevisions(ID id, Pageable pageable);
}

如何编写自定义查询,以获取特定用户在两个日期之间对某个实体的所有修订。

注意,我已经向存储用户id和修改日期的user_rev_entity表添加了额外的列。如果我将这个表与entity_aud表连接起来,就可以得到结果。

以下是我的审计表的脚本。

代码语言:javascript
复制
CREATE TABLE `user_rev_entity` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `timestamp` bigint(20) NOT NULL,
  `created_by` bigint(20) NOT NULL,
  `created_date` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

CREATE TABLE `revchanges` (
  `rev` int(11) NOT NULL,
  `entityname` varchar(255) DEFAULT NULL,
  KEY `FK_et6b2lrkqkab5mhvxkv861n8h` (`rev`),
  CONSTRAINT `FK_et6b2lrkqkab5mhvxkv861n8h` FOREIGN KEY (`rev`) REFERENCES `user_rev_entity` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `roles_aud` (
  `role_id` bigint(20) NOT NULL,
  `rev` int(11) NOT NULL,
  `revtype` tinyint(4) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  `description_mod` bit(1) DEFAULT NULL,
  `display_name` varchar(255) DEFAULT NULL,
  `display_name_mod` bit(1) DEFAULT NULL,
  `is_enabled` bit(1) DEFAULT NULL,
  `enabled_mod` bit(1) DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL,
  `title_mod` bit(1) DEFAULT NULL,
  PRIMARY KEY (`role_id`,`rev`),
  KEY `FK_pkqm51vsc35w2axvnns4bpas9` (`rev`),
  CONSTRAINT `FK_pkqm51vsc35w2axvnns4bpas9` FOREIGN KEY (`rev`) REFERENCES `user_rev_entity` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

因此,基本上我是在寻找特定用户在特定时间内对某个实体所做的所有更改。

将会有更多这样的实体。

EN

回答 3

Stack Overflow用户

发布于 2016-03-27 02:00:31

Spring Data Envers不支持自定义查询,就像您在spring data jpa中所习惯的那样。它所做的就是提供方便的RevisionRepository接口。

但是,您可以使用Revisions<N, T> findRevisions(ID id)方法并应用服务层中的过滤器。这里有一个例子。

代码语言:javascript
复制
@Service
public UserService {
    @Resource
    private UserRepository userRepository;

    public List<Revision<Integer, User>> findRevisionsBetweenDates(int id, Date startDate, Date endDate){
        return userRepository.findRevisions(id).getContent().stream().filter(
            revision -> revision.getEntity().getCreatedDate().getTime() > startDate.getTime() && 
                revision.getEntity().getCreatedDate().getTime() < endDate.getTime()
         ).collect(Collectors.toList());
}

这不是一个完美的匹配,因为您将从数据库中获取所有修订。但是,这是从数据库中保留抽象的最简单方法。

否则,您必须跳过Spring数据Envers,而使用Envers API。

祝你好运,致敬

票数 4
EN

Stack Overflow用户

发布于 2016-03-27 06:08:33

你看过AuditReaderFactory和AuditReader吗?

查看AuditReader的createQuery文档

与此AuditReader实例关联的查询创建者,可用于创建查询并在以后执行查询。

这将返回一个AuditQueryCreator,您可以使用该use创建如下查询:

代码语言:javascript
复制
AuditQuery query = getAuditReader().createQuery()
.forRevisionsOfEntity(MyEntity.class, false, true);

forRevisionsOfEntity有几个选项,请参阅AuditQueryCreator文档。

该查询应允许您使用AuditCriterion选择特定修订

与此相关的Hibernate envers文档:http://docs.jboss.org/hibernate/orm/5.0/userGuide/en-US/html_single/#revisions-of-entity

您可以使用与前一个查询相同的方式向此查询添加约束。还有一些额外的可能性:

  1. 使用AuditEntity.revisionNumber()您可以指定修订号的约束、预测和顺序,其中审核的实体被修改过。
  2. 类似地,您可以使用AuditEntity.revisionProperty(propertyName)指定修订实体属性上的约束、预测和顺序,与修改审核的实体的修订相对应。

使您可以如上所述地访问修订的类型(添加、修改、删除)。

编辑我尝试了一个实际的解决方案。我几乎没有envers和hibernate标准的经验,所以这可能是不正确的,但它可能会帮助您入门。

代码语言:javascript
复制
AuditQuery query = getAuditReader().createQuery()
        .forRevisionsOfEntity(MyEntity.class, false, true);

query.add(AuditEntity.revisionProperty("createdDate").gt(minDate))
        .add(AuditEntity.revisionProperty("createdDate").lt(maxDate))
        .add(AuditEntity.revisionProperty("createdBy").eq(userId));

//the documentation shows getSingleResult returns a number
//so i'm guessing a resultList also contains numbers
List<Number> resultList = query.getResultList();
票数 4
EN

Stack Overflow用户

发布于 2019-02-15 04:37:50

要获得所有修订,您可以简单地执行以下操作:

代码语言:javascript
复制
AuditQuery query = auditReader.createQuery().forRevisionsOfEntity(MyEntity.class, false, false);
List<Object[]> result = query.getResultList();
// and loop over the result list
for (Object[] tuple : result) {Item item = (Item) tuple[0];}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36008394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档