Làm cách nào để chúng tôi đếm các hàng bằng các phiên bản cũ của Hibernate (~ 2009)?


242

Ví dụ: nếu chúng ta có một bảng Sách, làm thế nào chúng ta sẽ đếm tổng số hồ sơ sách với chế độ ngủ đông?

Câu trả lời:


310

Đối với các phiên bản cũ hơn của Hibernate (<5.2):

Giả sử tên lớp là Sách:

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

Nó ít nhất là a Number, rất có thể là a Long.


10
Nó trả lại lâu.
dj_segfault

10
Như @Salandur gợi ý, "Nó ít nhất là một Số" và loại Số có các phương thức "intValue ()", "longValue ()", vì vậy chúng tôi có thể dễ dàng có được loại nguyên thủy mong muốn mà chúng tôi muốn: ((Số) tiêu chí.uniqueResult ()). intValue ()
Jerry Tian

5
Nếu không thể tìm thấy ánh xạ thực thể bằng cách sử dụng tham số chuỗi cho phương thức tạo tiêu chí, session.createCriteria (Book. Class) cũng có thể được sử dụng
Tobias M

5
Giống như @MontyBongo đã nói, tôi thực sự phải tham khảo lớp học như thế này: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney

2
Sau đó, bạn không nên sử dụng một cơ sở dữ liệu hợp lý;). Giá trị tối đa của dài là 9,223372037 × 10¹⁸, đó là laaaaaaaaaarge
Salandur

102

Trong Java tôi thường cần trả về int và sử dụng mẫu này:

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

1
Câu trả lời được chấp nhận cho câu hỏi này không hiệu quả với tôi, nhưng bạn thì có. Cảm ơn!
Jason Nichols

Đây có phải là cách nhanh nhất và rẻ nhất để có được số lượng truy vấn không? ý tôi là ngủ đông khôn ngoan
kommradHomer 16/03 '

57
Điểm quan trọng của việc sử dụng ORM là gì nếu chúng ta kết thúc việc mã hóa SQL?
nhiệt

Đó là mối quan tâm chính của tôi (sử dụng SQL thay vì HQL). Tôi phải sử dụng CHỌN lồng nhau chỉ để đếm số lượng hàng xuất hiện sau khi tham gia bên ngoài bên trái (Tôi không tìm thấy cách thực hiện đúng của tham gia bên ngoài bên trái trong chế độ ngủ đông).
Pramod

15
Trước hết, giải pháp này không sử dụng SQL, đó là HQL. Và sử dụng tính (*) thay vì 'select Count (e) từ E e' hoặc tiêu chí hoạt động với @EmbeddedId và cơ sở dữ liệu không hỗ trợ đếm tuple (ví dụ: MySQL, trong đó các truy vấn như 'select Count ((a, b) ) từ bảng1 'không hoạt động).
BrunoJCM

43

Đây là những gì tài liệu ngủ đông chính thức nói với chúng tôi về điều này:

Bạn có thể đếm số lượng kết quả truy vấn mà không cần trả lại chúng:

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

Tuy nhiên, nó không phải lúc nào cũng trả về Integerthể hiện, vì vậy tốt hơn là sử dụng java.lang.Numbercho an toàn.


1
+1 cho câu trả lời đưa ra phương pháp được đề xuất cho nhóm Hibernate.
Tom

3
Đối với tôi, điều này đã cho "java.lang.ClassCastException: java.lang.Long không thể được chuyển thành java.lang.Integer" nhưng chuyển sang Long thay vì hoạt động ...
rogerdpack

2
@rogerdpack điều này là do Hibernate đã thay đổi loại được trả về trong 3.5 thành Long: Community.jboss.org/wiki/HibernateCoreMigrationGuide35
máy móc

1
Loại trả về cho hàm đếm có thể được tìm thấy trong org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Guillaume Husta

12

Bạn có thể thử count(*)

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

Trong trường hợp Bookslà tên tắt class- không phải là bảng trong cơ sở dữ liệu.


xin lỗi nhưng nó không hoạt động với Java và Hibernate :( (Tôi đã thay thế int bằng Integer, như trong Java để tạo kiểu.)
thợ thủ công

Nó nên hoạt động - với Integer thay vì int? Bạn cần đặt tên lớp trong HQL, không phải tên bảng - là điều duy nhất tôi có thể nghĩ có thể sai
Jon Spokes

1
Tôi tin rằng bài viết trực tiếp bên dưới này phù hợp hơn với các nguyên tắc Hibernate cốt lõi.
Matt Sidesinger

Đối với tôi nó không hoạt động với java và ngủ đông. Thay vào đó, phải làm gì?
rParvathi

6

Nếu bạn đang sử dụng Hibernate 5+, thì truy vấn sẽ được sửa đổi thành

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

Hoặc nếu bạn cần TypedQuery

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

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

Nó sẽ là `` `Long Count = (Long) session.createQuery (" select Count (1) từ Book "). UniqueResult ();` `` nó sẽ cải thiện hiệu suất
rajadilipkolli

1

Điều này hoạt động trong Hibernate 4 (Đã thử nghiệm).

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

Trong đó getCienSession () là:

@Autowired
private SessionFactory sessionFactory;


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

1

Rất dễ dàng, chỉ cần chạy truy vấn JPQL sau đây:

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

Lý do chúng tôi đưa ra Numberlà một số cơ sở dữ liệu sẽ quay trở lại Longtrong khi các cơ sở dữ liệu khác sẽ quay trở lại BigInteger, vì vậy, vì tính di động, tốt hơn hết bạn nên chuyển sang a Numbervà nhận một inthoặc a long, tùy thuộc vào số lượng hàng bạn dự kiến ​​sẽ được tính.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.