เราจะนับจำนวนแถวโดยใช้ Hibernate รุ่นเก่า (~ 2009) ได้อย่างไร


242

ตัวอย่างเช่นถ้าเรามีโต๊ะหนังสือเราจะนับจำนวนระเบียนหนังสือทั้งหมดด้วยโหมดไฮเบอร์เนตได้อย่างไร

คำตอบ:


310

สำหรับ Hibernate รุ่นเก่ากว่า (<5.2):

สมมติว่าชื่อคลาสเป็น Book:

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

มันเป็นอย่างน้อยมีแนวโน้มมากที่สุดNumberLong


10
มันกลับมานาน
dj_segfault

10
ตามที่ @Salandur แนะนำว่า "อย่างน้อยที่สุดก็เป็น Number" และประเภท Number มีวิธีการ "intValue ()", "longValue ()" ดังนั้นเราสามารถรับประเภทดั้งเดิมที่ต้องการได้อย่างง่ายดาย: ((Number) criteria.uniqueResult ()). intValue ()
Jerry Tian

5
หากไม่พบการแมปเอนทิตีโดยใช้พารามิเตอร์สตริงกับวิธีสร้างเกณฑ์คุณสามารถใช้ session.createCriteria (Book.class) ได้ด้วย
Tobias M

5
เช่นเดียวกับ @MontyBongo กล่าวว่าที่จริงผมมีการอ้างถึงระดับเช่นนี้: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney

2
จากนั้นคุณไม่ควรใช้ฐานข้อมูลที่มีเหตุผล;) ค่าสูงสุดของความยาวคือ 9,223372037 ×10¹⁸ซึ่งเป็น
laaaaaaaaaarge

102

ใน Java ฉันมักจะต้องการคืน int และใช้แบบฟอร์มนี้:

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

1
คำตอบที่ยอมรับได้สำหรับคำถามนี้ไม่ได้ผลสำหรับฉัน แต่คุณทำแล้ว ขอบคุณ!
Jason Nichols

นี่เป็นวิธีที่เร็วและถูกที่สุดในการนับจำนวนข้อความค้นหาหรือไม่ ฉันหมายถึง hibernate-wise
kommradHomer

57
จุดประสงค์ของการใช้ ORM คืออะไรถ้าเราลงเอยด้วยการเข้ารหัส SQL อย่างไรก็ตาม
ร้อน

นั่นคือความกังวลหลักของฉัน (ใช้ SQL แทน HQL) ฉันต้องใช้ซ้อน SELECT เพื่อนับจำนวนแถวที่มาหลังจากการเข้าร่วมด้านนอกด้านซ้าย (ฉันไม่พบการใช้งานการเข้าร่วมด้านนอกด้านซ้ายอย่างเหมาะสมในโหมดไฮเบอร์เนต)
Pramod

15
ก่อนอื่นโซลูชันนี้ไม่ได้ใช้ SQL เป็น HQL และการใช้ count (*) แทน 'select count (e) จาก E e' หรือเกณฑ์ทำงานกับ @EmbeddedId และฐานข้อมูลที่ไม่รองรับการนับ tuple (เช่น MySQL ที่มีคำสั่งเช่น 'select count ((a, b) ) จาก table1 'ไม่ทำงาน)
BrunoJCM

43

นี่คือสิ่งที่เอกสารจำศีลอย่างเป็นทางการบอกเราเกี่ยวกับสิ่งนี้:

คุณสามารถนับจำนวนผลลัพธ์การสืบค้นโดยไม่ต้องส่งคืน:

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

อย่างไรก็ตามมันจะไม่ส่งคืนIntegerอินสแตนซ์เสมอไปดังนั้นจึงควรใช้java.lang.Numberเพื่อความปลอดภัย


1
+1 สำหรับคำตอบที่ให้วิธีการแนะนำกับทีมไฮเบอร์เนต
Tom

3
สำหรับฉันสิ่งนี้ให้ "java.lang.ClassCastException: java.lang.Long ไม่สามารถส่งไปยัง java.lang.Integer" แต่การส่งไปยัง Long แทนใช้งานได้ ...
rogerdpack

2
@rogerdpack นี่เป็นเพราะ Hibernate เปลี่ยนประเภทที่ส่งคืนใน 3.5 เป็น Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
เครื่องจักร

1
ชนิดส่งคืนสำหรับฟังก์ชันการนับสามารถพบได้ในorg.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Guillaume Husta

12

คุณสามารถลอง count(*)

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

ไหนBooksเป็นชื่อที่ปิดclass- ไม่ตารางในฐานข้อมูล


ขอโทษ แต่มันไม่ได้ทำงานกับ Java และ Hibernate :( (ฉันได้แทนที่ int ด้วย Integer เนื่องจากมันอยู่ใน Java สำหรับการคัดเลือกนักแสดง)
Craftsman

ควรใช้กับ Integer แทนที่จะเป็น int? คุณต้องใส่ชื่อคลาสใน HQL ไม่ใช่ชื่อตาราง - เป็นสิ่งเดียวที่ฉันสามารถคิดได้ว่าอาจผิด
Jon Spokes

1
ฉันเชื่อว่าการโพสต์ด้านล่างนี้จะสอดคล้องกับหลักการไฮเบอร์เนตหลัก
Matt Sidesinger

สำหรับฉันมันไม่ได้ทำงานกับ java และจำศีล จะทำอย่างไรดี
rParvathi

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 count (1) จาก 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ดังนั้นเพื่อความสะดวกในการพกพาคุณจะดีกว่าที่จะส่งNumberและรับintหรือlongขึ้นอยู่กับจำนวนแถวที่คุณคาดหวังที่จะนับ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.