首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过示例将时间戳范围与JPA查询匹配

通过示例将时间戳范围与JPA查询匹配
EN

Stack Overflow用户
提问于 2021-10-19 14:17:02
回答 1查看 236关注 0票数 1

JPA有一个非常简洁的选项,可以通过示例进行查询,如这里所解释的:按例查询

有没有办法使用这个系统在两次之间匹配一个有时间戳的对象?

例如:我在数据库中记录了销售额。我想在2021年10月20日07:00到13:00之间拿出ID: 7的所有商品。

在代码中,我将在存储库接口中创建一个查询:

代码语言:javascript
运行
复制
@Query("SELECT s FROM Sale s "
         + "WHERE s.id IS ?1 "
         + "AND s.timestamp > ?2 "
         + "AND s.timestamp < ?3"
)
List<Sale> getSalesForIdBetweenTimestamps(
    Long ID,
    Timestamp after,
    Timestamp before
);

然后,...and从服务中调用它,但是通过示例匹配,我可以这样调用它:

代码语言:javascript
运行
复制
Example<Sale> saleExample = Example.of(new Sale().withID(7));
List<Sale> salesWithID = this.salesRepository.findAll(saleExample);

...which看起来更整洁,不需要在存储库中编写。

我知道如何提供ID来查找该项目的所有销售,我甚至可以创建一个自定义匹配器使用这个类,以便在单个时间之前和之后执行。我可以通过避免整个“通过示例查询”系统来使用不同的解决方案,这就是我现在正在做的事情,但是我想使用它,但我不知道如何在两次之间进行匹配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-26 13:38:36

我在规格说明中找到了一个解决方案,这要归功于这个问题

规范是由许多谓词构建的,这些谓词既可以手工编写,也可以从示例中提取。这意味着创建一个示例可以使规范更易于编写和阅读,然后您可以对其进行调整,使其具有示例所不提供的功能。

在我的例子中,创建规范的函数如下所示:

代码语言:javascript
运行
复制
public Specification<Sale> getSpecFromDatesAndExample(
      final Optional<Timestamp> after,
      final Optional<Timestamp> before,
      final Example<Sale> example
) {
    return (root, query, builder) -> {

      final List<Predicate> predicates = new ArrayList<>();

      after.ifPresent(timestamp -> predicates.add(builder.greaterThan(root.get("timestamp"), timestamp)));
      before.ifPresent(timestamp -> predicates.add(builder.lessThan(root.get("timestamp"), timestamp)));

      predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));

      return builder.and(predicates.toArray(new Predicate[0]));
   };
}

然后,可以将..which传递到存储库中,如下所示:

代码语言:javascript
运行
复制
public List<SaleDTO> getSales(
      final Pageable pageable,
      final Optional<String> productName,
      final Optional<String> after,
      final Optional<String> before,
      final Optional<Long> customerID,
      final Optional<Long> quantity
)
{
Sale example = new Sale();
productName.ifPresent(example::setProductName);
customerID.ifPresent(example::setCustomerID);
quantity.ifPresent(example::setQuantity);

Optional<Timestamp> afterTimestamp = after.map(Timestamp::valueOf);
Optional<Timestamp> beforeTimestamp = before.map(Timestamp::valueOf);

List<SaleDTO> saleList = new ArrayList<>();

return this.saleRepository.findAll(getSpecFromDatesAndExample(afterTimestamp, beforeTimestamp, Example.of(example)), pageable);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69632540

复制
相关文章

相似问题

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