【问题标题】:Create Search Specification with Dates range使用日期范围创建搜索规范
【发布时间】:2021-12-31 04:34:23
【问题描述】:

我想创建一个搜索规范,我可以在其中根据日期范围选择数据。我试过这个:

@Getter
@Setter
public class BillingSummarySearchParams {

    private LocalDateTime startDate;

    private LocalDateTime endDate;
}

搜索规范

public List<BillingSummaryFullDTO> findBillingInvoicesSummary(BillingSummarySearchParams params)
    {
        Specification<BillingSummary> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (params.getStartDate() != null | params.getEndDate() != null) {
                predicates.add(cb.like(cb.lower(root.get("startDate")), "%" + params.getStartDate() + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        return billingSummaryService.findAll(spec).stream().map(billingSummaryMapper::toFullDTO).collect(Collectors.toList());
    }

搜索 SQL

public List<BillingSummary> findAll(Specification<BillingSummary> spec)
    {
        String hql = "select e from " + BillingSummary.class.getName() + " e where e.createdAt BETWEEN :startDate AND :endDate ORDER BY e.createdAt DESC";
        TypedQuery<BillingSummary> query = entityManager.createQuery(hql, BillingSummary.class).setParameter("startDate", spec).setParameter("endDate", spec);
        List<BillingSummary> list = query.getResultList();
        return list;
    }

我不清楚如何使用 2 个工作日期且只有一个日期来构建规范。

从规范对象中获取日期的正确方法是什么?

【问题讨论】:

    标签: java spring spring-boot spring-data-jpa


    【解决方案1】:

    我认为您误解了 Specifications 的用途。它们不打算与“旧”类型的查询结合使用。如果您将 Specification 设置为它们的参数,它应该会导致错误,因为 jpa 提供者不知道如何使用该对象。

    相反,它们的实现是为了更容易在 spring 数据中创建和使用条件查询。使它们工作的第一步是在您的存储库中实现JpaSpecificationExecutor。该接口包含findAll(Specification&lt;T&gt; spec) 等方法,spring 会自动为您的存储库创建这些方法。 Spring 在后台生成条件查询,并将您在规范中创建的谓词添加到其中。

    @Repository
    public interface BillingSummaryRepository extends JpaRepository<BillingSummary, Long>, JpaSpecificationExecutor<BillingSummary> {
        //Other methods
    }
    
    Specification<BillingSummary> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (params.getStartDate() != null | params.getEndDate() != null) {
                predicates.add(cb.like(cb.lower(root.get("startDate")), "%" + params.getStartDate() + "%"));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
    };
    List<BillingSummary> summaries = billingSummaryService.findAll(spec, Sort.by(Sort.Direction.DESC, "createdAt"));
    

    【讨论】:

    • 我在这里看到一个问题:predicates.add(cb.like(cb.lower(root.get("startDate")), "%" + params.getStartDate() + "%")); 我在这两个日期都需要什么配置?
    • 可能想改用betweengreaterThanOrEqualTo & lessThanOrEqualTo。见stackoverflow.com/q/41806152/9712270
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多