Java Hibernate 计数行
Posted
技术标签:
【中文标题】Java Hibernate 计数行【英文标题】:Java Hibernate Count Rows 【发布时间】:2017-04-18 09:20:26 【问题描述】:我将 Java8 与 Hibernate5 和 JPA2 一起使用。我想计算结果集中的行数。我有以下有效的代码,但是,我想知道是否有更有效的方法?我认为下面的代码首先查询整个结果集并计算行数。
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();
有没有办法让 SQL 执行 count(*)
?
更新
感谢下面的@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();
问题
如何使用Job
参数设置where
子句?
更多信息:
+--------+ +------------+ +-----+
| rating | | rating_job | | job |
+--------+ +------------+ +-----+
| ID | | RAT_ID | | ID |
| | | JOB_ID | | |
+--------+ +------------+ +-----+
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;
更新
感谢@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;
【问题讨论】:
如果你想限制一些“工作”然后加入那个实体并应用 where 子句,否则你没有使用你的参数。日志会告诉您生成了什么 SQL,因此这应该是高效的基础 谢谢尼尔。这是我的问题,我该如何做where
子句?如何将Job
对象添加到where
子句? cq.where(/*rating is equal to job*/)
@Richard 检查我的更新。
【参考方案1】:
在 JPA2 中使用 CriteriaQuery
你可以这样做:
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));
创建一个CriteriaQuery<Long>
而不是CriteriaQuery<Rating>
,这样当您计算criteria.from(Rating.class)
结果的行数时,它会为您提供行数。
编辑:
我编辑了答案代码,以在查询中包含对Job
给定参数的测试,尊重您的实体映射。
然后要执行您的查询,您需要编写:
TypedQuery<Country> query = em.createQuery(criteria);
query.setParameter(param, yourJobObject);
Long resultsCount = query.getSingleResult();
请注意,您需要将 query.getSingleResult()
包装在 try ..catch
块中,因为它可能会引发错误。
参考:
请查看the answer here 和此JPA Criteria API Queries tutorial 以进一步阅读。
【讨论】:
谢谢,但是你把 Job 参数放在哪里了? 谢谢,但我不确定这是否可行,因为我的Rating
表使用连接表。我会更新上面的描述。
我想它快到了。我现在得到:Named parameter [param0] not set
。抱歉,我看到了你的修改,这可能会解决它。
@Richard 您是否按照我在编辑中的建议使用了query.setParameter(param, yourJobObject);
?【参考方案2】:
只是一个例子,我用它来检查实体的存在。
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();
如果它们不是任何标签,它只会向我发送0
,否则会发送现有标签的数量。
【讨论】:
【参考方案3】:只需像这样使用 rowCount 添加投影:
return (Long) criteria.setProjection(Projections.rowCount()).uniqueResult();
结果将是Long
类型的行数对象
【讨论】:
谢谢,这看起来很有用。但是,我确实收到以下编译错误:The method setProjection(Projection) is undefined for the type CriteriaQuery<Rating>
因为它不是 JPA Criteria(答案是 Hibernates 自己的 API,所以放弃可移植性!)
我猜这也忽略了Job
参数?
啊,我的错,这个答案是针对 org.hibernate.Criteria(hibernate) 而不是 javax.persistence.criteria.CriteriaQuery(JPA)。以上是关于Java Hibernate 计数行的主要内容,如果未能解决你的问题,请参考以下文章