简体   繁体   English

Java Hibernate Count Rows

[英]Java Hibernate Count Rows

I am using Java8 with Hibernate5 and JPA2. 我使用Java8与Hibernate5和JPA2。 I would like to count the number of rows in a result set. 我想计算结果集中的行数。 I have the following code that works, however, I would like to know if there's a more efficient way of doing it? 我有以下代码可行,但是,我想知道是否有更有效的方法吗? I think the code below first queries the entire result set and the counts the rows. 我认为下面的代码首先查询整个结果集并计算行数。

    final EntityManagerFactory entityManagerFactory = entityManager.getEntityManagerFactory();
    final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
    CriteriaQuery<Rating> criteria = criteriaBuilder.createQuery(Rating.class);
    Root<Rating> root = criteria.from(Rating.class);
    ParameterExpression<Job> param = criteriaBuilder.parameter(Job.class);

    TypedQuery<Rating> queryRating = entityManager.createQuery(criteria);
    queryRating.setParameter(param, job);
    int results = queryRating.getResultList().size();

Is there a way of rather making the SQL do a count(*) ? 有没有办法让SQL做一个count(*)

UPDATE UPDATE

Thanks to @chsdk below, I have a revised version of code: 感谢下面的@chsdk,我有一个修改后的代码版本:

    CriteriaBuilder qb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Long> cq = qb.createQuery(Long.class);
    cq.select(qb.count(cq.from(Rating.class)));
    cq.where(/*your stuff*/);
    return entityManager.createQuery(cq).getSingleResult();

Question

How do I set the where clause with the Job parameter? 如何使用Job参数设置where子句?

More info: 更多信息:

+--------+   +------------+    +-----+
| rating |   | rating_job |    | job |
+--------+   +------------+    +-----+
|   ID   |   |   RAT_ID   |    |  ID |
|        |   |   JOB_ID   |    |     |
+--------+   +------------+    +-----+

Rating.java Rating.java

@ManyToOne(fetch=FetchType.EAGER)
@JoinTable
(
    name="rating_job",
    joinColumns={ @JoinColumn(name="RAT_ID", referencedColumnName="ID") },
    inverseJoinColumns={ @JoinColumn(name="JOB_ID", referencedColumnName="ID") }
)
private Job job;

UPDATE UPDATE

Thanks to @chsdk, here is my version that works: 感谢@chsdk,这是我的版本:

    final EntityManagerFactory entityManagerFactory = entityManager.getEntityManagerFactory();
    final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
    CriteriaQuery<Long> criteria = criteriaBuilder.createQuery(Long.class);
    Root<Rating> root = criteria.from(Rating.class);
    ParameterExpression<Job> param = criteriaBuilder.parameter(Job.class);
    criteria.select(criteriaBuilder.count(root)).where(criteriaBuilder.equal(root.get("job"), param));
    TypedQuery<Long> queryRating = entityManager.createQuery(criteria);
    queryRating.setParameter(param, job);
    Long results = queryRating.getSingleResult();

    return results;

In JPA2 with CriteriaQuery you can do it this way: 在使用CriteriaQuery JPA2中 ,您可以这样做:

final CriteriaBuilder criteriaBuilder = entityManagerFactory.getCriteriaBuilder();
CriteriaQuery<Long> criteria = qb.createQuery(Long.class);
Root<Country> root = criteria.from(Rating.class);
criteria.select(criteriaBuilder.count(root));

ParameterExpression<Job> param = criteriaBuilder.parameter(Job.class);
criteria.where(criteriaBuilder.equal(root.get("job"), param));

Make a CriteriaQuery<Long> instead of CriteriaQuery<Rating> so it gives you a row count when you count the rows of your criteria.from(Rating.class) result. 创建一个CriteriaQuery<Long>而不是CriteriaQuery<Rating>这样当你计算你的criteria.from(Rating.class)结果的行时,它会给你一个行计数。

Edit: 编辑:

I edited the answer code to include testing over Job given parameter in the query, respecting your entities mapping. 我编写了答案代码,在查询中包含对Job given参数的测试,尊重您的实体映射。

Then to execute your query you will need to write: 然后执行查询,您需要写:

TypedQuery<Country> query = em.createQuery(criteria);
query.setParameter(param, yourJobObject);
Long resultsCount = query.getSingleResult();

Note that you need to wrap the query.getSingleResult() in a try ..catch block because it may throw an error. 请注意,您需要将query.getSingleResult()包装在try ..catch块中,因为它可能会引发错误。

Refernce: Refernce:

Please check the answer here and this JPA Criteria API Queries tutorial for further reading. 此处查看答案以及此JPA Criteria API查询教程以供进一步阅读。

Just an example, I use that to check the existence of entity. 举个例子,我用它来检查实体的存在。

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> cQuery = builder.createQuery(Long.class);
Root<Tag> from = cQuery.from(Tag.class);
cQuery.where(from.get("ID").in(ids));

CriteriaQuery<Long> nbTags = cQuery.select(builder.count(from));

return em.createQuery(nbTags).getSingleResult();

It just send me an 0 if their isn't any tags, otherwise the number of existing tags. 它只是发送给我一个0如果他们不是任何标签,否则现有标签的数量。

Just add projection using rowCount like this : 只需使用rowCount添加投影,如下所示:

return (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();

The result will be in Long type object of number of rows 结果将在行数的Long类型对象中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM