Como contamos linhas usando versões mais antigas do Hibernate (~ 2009)?

242

Por exemplo, se tivermos uma tabela Livros, como contaríamos o número total de registros de livros com hibernação?

artesão
fonte

Respostas:

310

Para versões mais antigas do Hibernate (<5.2):

Supondo que o nome da classe seja Livro:

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

É pelo menos um Number, provavelmente um Long.

Salandur
fonte
10
Retorna um longo.
dj_segfault
10
Como o @Salandur sugere, "É pelo menos um número" e o tipo de número tem os métodos "intValue ()", "longValue ()", para que possamos obter facilmente o tipo primitivo desejado: (critérios (número)). ()) intValue ()
Jerry Tian
5
Se o mapeamento da entidade não puder ser encontrado usando um parâmetro string para o método de criação de critérios, o session.createCriteria (Book.class) também poderá ser usado.
Tobias M
5
Como @MontyBongo disse, eu realmente tive que consultar a classe como este: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney
2
Então você não deve usar um banco de dados racional;). Valor máximo de tempo é 9,223372037 × 10¹⁸, que é laaaaaaaaaarge
Salandur
102

Em Java, geralmente preciso retornar int e usar este formulário:

int count = ((Long)getSession().createQuery("select count(*) from Book").uniqueResult()).intValue();
marioosh
fonte
1
A resposta aceita para esta pergunta não funcionou para mim, mas a sua funcionou. Obrigado!
Jason Nichols
essa é a maneira mais rápida e barata de contar uma consulta? Eu quero dizer hibernar-wise
kommradHomer
57
Qual é o sentido de usar um ORM se acabarmos codificando o SQL?
thermz
Essa é a minha principal preocupação (usando SQL em vez de HQL). Eu tenho que usar SELECT aninhado apenas para contar o número de linhas que vem após a junção externa esquerda (não encontrei a implementação adequada da junção externa esquerda no hibernate).
Pramod
15
Primeiro, esta solução não usa SQL, é HQL. E usar count (*) em vez de 'select count (e) de E e' ou critérios funciona com o @EmbeddedId e bancos de dados que não suportam contagem de tuplas (por exemplo, MySQL, onde pesquisas como 'select count ((a, b) ) da tabela1 'não funciona).
BrunoJCM
43

Aqui está o que os documentos oficiais do hibernate nos dizem sobre isso:

Você pode contar o número de resultados da consulta sem retorná-los:

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

No entanto, nem sempre ele retorna a Integerinstância, portanto, é melhor usá-lo java.lang.Numberpor segurança.

Antonio
fonte
1
+1 para obter uma resposta que forneça o método recomendado à equipe do Hibernate.
Tom
3
Para mim, isso deu "java.lang.ClassCastException: java.lang.Long não pode ser convertido para java.lang.Integer", mas a conversão para um Long funciona ...
rogerdpack
2
@rogerdpack, isso ocorre porque o Hibernate alterou o tipo retornado em 3.5 para Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
machinery
1
O tipo de retorno para a função count pode ser encontrado em org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Guillaume Husta
12

Você poderia tentar count(*)

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

Onde Booksestá o nome fora da class- não a tabela no banco de dados.

Jon Spokes
fonte
Lamentamos, mas não o seu trabalho com Java e Hibernate :( (eu fiz substituir int com Integer, como é em Java para o tipo de fundição.)
artesão
Deve funcionar - com Inteiro em vez de int? Você precisa colocar o nome da classe no HQL, não o nome da tabela - é a única coisa que posso pensar que pode estar errado
Jon Spokes
1
Acredito que o post diretamente abaixo disso esteja mais alinhado com os princípios básicos do Hibernate.
Matt Sidesinger
para mim não está funcionando com java e hibernação. o que fazer em vez disso?
RParvathi 01/07/19
6

Se você estiver usando o Hibernate 5+, a consulta será modificada como

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

Ou se você precisar de TypedQuery

Long count = session.createQuery("select count(1) from  Book",Long.class)
                        .getSingleResult();
rajadilipkolli
fonte
6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();
xrcwrn
fonte
Deve be``` contagem longa = (Long) session.createQuery ( "select count (1) do livro") uniqueResult (); `` `ele irá melhorar o desempenho.
rajadilipkolli
1

Isso funciona no Hibernate 4 (testado).

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

Onde getCurrentSession () é:

@Autowired
private SessionFactory sessionFactory;


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

É muito fácil, basta executar a seguinte consulta JPQL:

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

A razão pela qual estamos lançando Numberé que alguns bancos de dados retornam Longenquanto outros retornam BigInteger, portanto, para maior portabilidade, é melhor converter para ae Numberobter uma intou a long, dependendo de quantas linhas você espera que sejam contadas.

Vlad Mihalcea
fonte