Spring JPA示例匹配器比较日期条件。

11

我正在使用Spring JPA,并通过Example Matcher获取数据列表。以下是源代码:

public Page<TranxLog> findAllByConditions(TranxReportFormModel formModel, Pageable page) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withNullHandler(ExampleMatcher.NullHandler.IGNORE)
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase()
                .withIgnoreNullValues();
        Example<TranxLog> example = Example.of(formModel.getTranxLog(), matcher);
        return tranxlogRepository.findAll(example, page);
    }

现在,我有一个搜索页面,其中有formDatetoDate两个字段,需要将它们与TranxLog中的DateTime字段进行比较。我尝试使用.withMatcher()方法,但无法找到一种比较日期的方法。

您有什么思路吗?谢谢。

2个回答

14

你也可以继承自JpaSpecificationExecutor,然后使用QueryByExamplePredicateBuilder从示例中获取谓词。

在你的存储库中:

public interface TranxlogRepository extends JpaRepository<Tranxlog, Long>, JpaSpecificationExecutor<Tranxlog>{ 
}

在你的serviceImp中

public Specification<TranxLog> getSpecFromDatesAndExample(
  LocalDateTime from, LocalDateTime to, Example<TranxLog> example) {

    return (Specification<TranxLog>) (root, query, builder) -> {
         final List<Predicate> predicates = new ArrayList<>();

         if (from != null) {
            predicates.add(builder.greaterThan(root.get("dateField"), from));
         }
         if (to != null) {
            predicates.add(builder.lessThan(root.get("dateField"), to));
         }
         predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));

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

在你的serviceImp中也是如此:

public Page<TranxLog> findAllByConditions(TranxReportFormModel formModel, Pageable page) {
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withNullHandler(ExampleMatcher.NullHandler.IGNORE)
            .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
            .withIgnoreCase()
            .withIgnoreNullValues();
    Example<TranxLog> example = Example.of(formModel.getTranxLog(), matcher);
    return tranxlogRepository.findAll(getSpecFromDatesAndExample(from, to, Example.of(formModel.getTranxLog(), matcher)), page);
}

按照我的预期工作正常。我想从API端点提供的“from”日期(以纪元时间表示)中过滤记录。谢谢! - Akhil

3
你不能使用查询示例(query-by-example)进行这样的操作。可能最好的方法是构建一个“规范(Specification)”对象, 详情请参见Specification

它已经被弃用了。如何将示例和规范结合起来?在日期中我想要范围,但在主键中,我想要给出完整的值。 - Satish Patro
1
你不能将“按示例查询”和“规范”组合在一起,但是没有任何限制阻止你从实体创建一个规范。此外,“规范”并没有被弃用,只有“规范集”被弃用了(请注意末尾的s)。 - Jens Schauder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接