我们如何使用较旧版本的Hibernate(〜2009)计算行数?


242

例如,如果我们有一个表格Books,那么我们如何计算休眠状态下的图书记录总数?

Answers:


310

对于旧版本的Hibernate(<5.2):

假设类名是Book:

return (Number) session.createCriteria("Book")
                  .setProjection(Projections.rowCount())
                  .uniqueResult();

它至少是一个Number,很可能是一个Long


10
返回很长。
dj_segfault

10
正如@Salandur所建议的那样,“至少是一个数字”,并且Number类型具有“ intValue()”,“ longValue()”方法,因此我们可以轻松地获得所需的基本类型:((Number)条件.uniqueResult ())。intValue()
Jerry Tian

5
如果使用字符串参数无法找到创建标准方法的实体映射,则也可以使用session.createCriteria(Book.class)
Tobias M

5
就像@MontyBongo所说的,我实际上不得不参考这样的课程: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney 2013年

2
那么你不应该使用一个合理的数据库;)。long的最大值为9,223372037×10¹⁸,即laaaaaaaaaarge
Salandur

102

在Java中,我通常需要返回int并使用以下形式:

int count = ((Long)getSession().createQuery("select count(*) from Book").uniqueResult()).intValue();

1
这个问题的公认答案对我不起作用,但对您而言却有效。谢谢!
杰森·尼科尔斯

这是获取查询计数最快,最便宜的方法吗?我的意思是休眠方式
kommradHomer 2012年

57
如果我们最终还是对SQL进行编码,那么使用ORM有什么意义呢?
thermz 2012年

这是我主要关心的问题(使用SQL代替HQL)。我必须使用嵌套的SELECT来计算左外部连接之后的行数(我在休眠状态下未找到左外部连接的正确实现)。
Pramod 2012年

15
首先,此解决方案不使用SQL,而是HQL。并且使用count(*)代替'从E e中选择select(e)'或使用标准与@EmbeddedId和不支持元组计数的数据库一起使用(例如,MySQL,其中的查询类似于'select count((a,b) )从table1'无效)。
BrunoJCM 2012年

43

这是官方休眠文档告诉的内容我们的内容:

您可以计算查询结果的数量而无需返回它们:

( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()

但是,它并不总是返回Integer实例,因此java.lang.Number为安全起见最好使用。


1
+1是给出了Hibernate小组推荐方法的答案。
汤姆

3
对我来说,这给了“ java.lang.ClassCastException:无法将java.lang.Long强制转换为java.lang.Integer”,而是强制转换为Long却有效……
rogerdpack 2013年

2
@rogerdpack,这是因为Hibernate将3.5中的返回类型更改为Long:community.jboss.org/wiki/HibernateCoreMigrationGuide35
机械

1
计数函数的返回类型可以在org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunctionStandardBasicTypes.LONG
Guillaume Husta,

12

你可以试试 count(*)

Integer count = (Integer) session.createQuery("select count(*) from Books").uniqueResult();

Books的名称在哪里class-不是数据库中的表。


抱歉,但它不适用于Java和Hibernate:((我确实用Integer替换了int,因为它在Java中用于类型转换。)
Craftsman

它应该工作-使用Integer而不是int吗?您需要将类名放在HQL中,而不是表名中-这是我唯一认为可能是错误的事情
Jon Spokes

1
我认为,此位置正下方的帖子更符合Hibernate的核心原则。
Matt Sidesinger 09年

对我来说,它不能与Java和休眠一起使用。该怎么做呢?
rParvathi '16

6

如果您使用的是Hibernate 5+,则查询将被修改为

Long count = session.createQuery("select count(1) from  Book")
                    .getSingleResult();

或者如果您需要TypedQuery

Long count = session.createQuery("select count(1) from  Book",Long.class)
                        .getSingleResult();

6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();

它应该是“`long count =(Long)session.createQuery(“ select Book(1)from Book”)。uniqueResult();```它将提高性能
rajadilipkolli

1

这适用于Hibernate 4(已测试)。

String hql="select count(*) from  Book";
Query query= getCurrentSession().createQuery(hql);
Long count=(Long) query.uniqueResult();
return count;

其中getCurrentSession()是:

@Autowired
private SessionFactory sessionFactory;


private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}

1

非常简单,只需运行以下JPQL查询:

int count = (
(Number)
    entityManager
    .createQuery(
        "select count(b) " +
        "from Book b")
    .getSingleResult()
).intValue();

我们强制转换的原因Number是某些数据库将返回Long而另一些数据库将返回BigInteger,因此出于可移植性的考虑,最好将其强制转换为a Number并获取an int或a long,这取决于您希望计数的行数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.