使用 CriteriaBuilder 选择带有“where”的计数

Pau*_*eez 6 orm hibernate jpa

我正在尝试做这样的事情

SELECT COUNT(*) FROM Tickets WHERE ticketStatus = 3 AND ...
Run Code Online (Sandbox Code Playgroud)

但仅使用 JPA 提供的 CriteriaBuilder。这是我所拥有的:

private class Criteria {
    CriteriaBuilder builder;
    CriteriaQuery<TicketModel> query;
    Root<TicketModel> root;

    public Criteria() {
        builder = em.getCriteriaBuilder();
        query = builder.createQuery(TicketModel.class);
        root = query.from(TicketModel.class);
    }
}
public long getSearchResultsQuantity(SearchModel search) {
    Criteria c = new Criteria();
    List<Predicate> params = new ArrayList<Predicate>();

    if (search.getStartDate() != null && search.getEndDate() != null) {
        params.add(c.builder.between(c.root.get(TicketModel_.ticketDate), search.getStartDate(),
                search.getEndDate()));
    }

    if (search.getStatus() != -1) {
        params.add(c.builder.equal(c.root.get(TicketModel_.ticketStatus), search.getStatus()));
    }

    CriteriaQuery<Long> q = c.builder.createQuery(Long.class);

    return em.createQuery(
            q.select(c.builder.count(q.from(TicketModel.class))).where(params.toArray(new Predicate[] {})))
            .getSingleResult();
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试执行此查询时,我收到这样的异常:

org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.ticketStatus' [select count(generatedAlias0) from com.mif.spring.models.TicketModel as generatedAlias0 where generatedAlias1.ticketStatus=0]
Run Code Online (Sandbox Code Playgroud)

我在 Spring 有点笨手笨脚,所以任何帮助将不胜感激!

Jos*_*tin 8

问题是你正在混合根。

如果您为两个根创建相同的别名将起作用。

例如:

private class Criteria {
    CriteriaBuilder builder;
    CriteriaQuery<TicketModel> query;
    Root<TicketModel> root;


    public Criteria(String alias) {
        builder = em.getCriteriaBuilder();
        query = builder.createQuery(TicketModel.class);
        root = query.from(TicketModel.class);
        root.alias(alias);
    }
}
Run Code Online (Sandbox Code Playgroud)

进而

 Criteria c = new Criteria("someAlias");
 ...
 CriteriaQuery<Long> q = c.builder.createQuery(Long.class);
 Root<TicketModel> root = q.from(TicketModel.class);
 root.alias("someAlias");

 return em.createQuery(
         q.select(c.builder.count(root)).where(
params.toArray(new Predicate[] {})))
                .getSingleResult();
Run Code Online (Sandbox Code Playgroud)

也许您可能对JpaUtils类(我写的)感兴趣,您可以简单地使用它:

Long count = JpaUtils.count(em, criteria);

用于从任何条件查询中获取计数。