¿Cómo contamos las filas con versiones anteriores de Hibernate (~ 2009)?

242

Por ejemplo, si tenemos una tabla Libros, ¿cómo contamos el número total de registros de libros con hibernación?

artesano
fuente

Respuestas:

310

Para versiones anteriores de Hibernate (<5.2):

Suponiendo que el nombre de la clase es Libro:

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

Es al menos un Number, muy probablemente un Long.

Salandur
fuente
10
Vuelve un largo.
dj_segfault
10
Como sugiere @Salandur, "Es al menos un Número", y el tipo de Número tiene los métodos "intValue ()", "longValue ()", por lo que podemos obtener fácilmente el tipo primitivo deseado que queremos: ((Number) criterios.uniqueResult ()). intValue ()
Jerry Tian
55
Si no se puede encontrar el mapeo de la entidad usando un parámetro de cadena para el método de creación de criterios, session.createCriteria (Book.class) también se puede usar
Tobias M
55
Como dijo @MontyBongo, en realidad tenía que referirme a la clase así: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney
2
Entonces no deberías usar una base de datos racional;). El valor máximo de largo es 9,223372037 × 10¹⁸, que es laaaaaaaaaarge
Salandur
102

En Java, generalmente necesito devolver int y usar este formulario:

int count = ((Long)getSession().createQuery("select count(*) from Book").uniqueResult()).intValue();
marioosh
fuente
1
La respuesta aceptada para esta pregunta no funcionó para mí, pero la suya sí. ¡Gracias!
Jason Nichols
¿Es esta la forma más rápida y económica de contar una consulta?
Me
57
¿Cuál es el punto de usar un ORM si terminamos codificando SQL de todos modos?
thermz
Esa es mi principal preocupación (usar SQL en lugar de HQL). Tengo que usar SELECT anidado solo para contar el número de filas que vienen después de la combinación externa izquierda (no encontré la implementación adecuada de la combinación externa izquierda en hibernación).
Pramod
15
En primer lugar, esta solución no usa SQL, es HQL. Y usar count (*) en lugar de 'select count (e) from E e' o criterios funciona con @EmbeddedId y bases de datos que no admiten tuple count (por ejemplo, MySQL, donde consultas como 'select count ((a, b) ) de la tabla1 'no funciona).
BrunoJCM
43

Esto es lo que los documentos oficiales de hibernación nos dicen sobre esto:

Puede contar el número de resultados de la consulta sin devolverlos:

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

Sin embargo, no siempre devuelve Integerinstancia, por lo que es mejor usarlo java.lang.Numberpor seguridad.

Antonio
fuente
1
+1 para una respuesta que le da al equipo de Hibernate el método recomendado.
Tom
3
Para mí, esto dio "java.lang.ClassCastException: java.lang.Long no se puede lanzar a java.lang.Integer", pero en cambio a Long funciona ...
rogerdpack
2
@rogerdpack esto se debe a que Hibernate cambió el tipo devuelto en 3.5 a Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
maquinaria
1
El tipo de retorno para la función de conteo se puede encontrar en org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Guillaume Husta
12

Tu podrías intentar count(*)

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

¿Dónde Booksestá el nombre fuera de class- no la tabla en la base de datos.

Jon Spokes
fuente
Lo sentimos, pero no su trabajo con Java y Hibernate :( (lo hice reemplazar con int entero, como lo es en Java para la conversión de tipos.)
artesano
Debería funcionar, ¿con Integer en lugar de int? Debe poner el nombre de la clase en el HQL, no el nombre de la tabla, es lo único que puedo pensar que puede estar mal
Jon Spokes
1
Creo que la publicación directamente debajo de esto está más en línea con los principios básicos de Hibernate.
Matt Sidesinger
para mí no funciona con Java e Hibernate. ¿Qué hacer en su lugar?
rParvathi
6

Si está utilizando Hibernate 5+, la consulta se modificará como

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

O si necesitas TypedQuery

Long count = session.createQuery("select count(1) from  Book",Long.class)
                        .getSingleResult();
rajadilipkolli
fuente
6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();
xrcwrn
fuente
Debe ser `` 'Long count = (Long) session.createQuery ("select count (1) from Book"). UniqueResult (); `` `mejorará el rendimiento
rajadilipkolli
1

Esto funciona en Hibernate 4 (Probado).

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

Donde getCurrentSession () es:

@Autowired
private SessionFactory sessionFactory;


private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
LucianoDemuru
fuente
1

Es muy fácil, solo ejecute la siguiente consulta JPQL:

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

La razón por la que estamos enviando Numberes que algunas bases de datos regresarán, Longmientras que otras regresarán BigInteger, por lo que por razones de portabilidad, es mejor que envíe a Numbery obtenga un into a long, dependiendo de cuántas filas espera contar.

Vlad Mihalcea
fuente