2011-03-18 14 views
22

का उपयोग करके पेजिनेशन के लिए कुल पंक्ति गणना मैं अपने सिस्टम में एक इकाई के लिए "उन्नत खोज" कार्यक्षमता को कार्यान्वित कर रहा हूं जैसे कि उपयोगकर्ता कई स्थितियों (ईक, एन, gt, lt, आदि) का उपयोग करके उस इकाई को खोज सकता है। इस इकाई के गुणों पर। मैं जेपीए के मानदंड एपीआई का उपयोग गतिशील रूप से मानदंड क्वेरी उत्पन्न करने के लिए कर रहा हूं और फिर पेजिंग के समर्थन के लिए setFirstResult() & setMaxResults() का उपयोग कर रहा हूं। सभी इस बिंदु तक ठीक थे लेकिन अब मैं परिणाम ग्रिड पर परिणामों की कुल संख्या दिखाना चाहता हूं लेकिन मुझे मानदंड क्वेरी की कुल गणना प्राप्त करने के लिए सीधे आगे नहीं देखा गया।
यह कैसे मेरे कोड की तरह लग रहा है:जेपीए मानदंड एपीआई

CriteriaBuilder builder = em.getCriteriaBuilder(); 
CriteriaQuery<Brand> cQuery = builder.createQuery(Brand.class); 
Root<Brand> from = cQuery.from(Brand.class); 
CriteriaQuery<Brand> select = cQuery.select(from); 
. 
. 
//Created many predicates and added to **Predicate[] pArray** 
. 
. 
select.where(pArray); 
// Added orderBy clause 
TypedQuery typedQuery = em.createQuery(select); 
typedQuery.setFirstResult(startIndex); 
typedQuery.setMaxResults(pageSize); 
List resultList = typedQuery.getResultList(); 

मेरे परिणाम सेट बड़ा तो मैं गिनती क्वेरी के लिए मेरी निकाय लोड नहीं करना चाहते हो सकता है, इसलिए मुझ पर rowCount() विधि की तरह कुल संख्या प्राप्त करने के लिए कारगर तरीका बता मानदंड (मुझे लगता है कि वहां हाइबरनेट के मानदंड में)।

उत्तर

24

धन्यवाद व्लादिमीर! मैंने आपका विचार लिया और इसमें मेरी मौजूदा अनुमानों का उपयोग करने के लिए अलग-अलग गिनती क्वेरी का उपयोग किया। अंतिम कार्यान्वयन इस तरह दिखता है:

CriteriaBuilder builder = em.getCriteriaBuilder(); 
CriteriaQuery<Brand> cQuery = builder.createQuery(Brand.class); 
Root<Brand> from = cQuery.from(Brand.class); 
CriteriaQuery<Brand> select = cQuery.select(from); 
. 
. 
//Created many predicates and added to **Predicate[] pArray** 
. 
. 
CriteriaQuery<Long> cq = builder.createQuery(Long.class); 
cq.select(builder.count(cq.from(Brand.class))); 
// Following line if commented causes [org.hibernate.hql.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.enabled' [select count(generatedAlias0) from xxx.yyy.zzz.Brand as generatedAlias0 where (generatedAlias1.enabled=:param0) and (lower(generatedAlias1.description) like :param1)]] 
em.createQuery(cq); 
cq.where(pArray); 
Long count = em.createQuery(cq).getSingleResult(); 
. 
. 
select.where(pArray); 
. 
. 
// Added orderBy clause 
TypedQuery typedQuery = em.createQuery(select); 
typedQuery.setFirstResult(startIndex); 
typedQuery.setMaxResults(pageSize); 
List resultList = typedQuery.getResultList() 

हालांकि इस ठीक काम कर रहा है, लेकिन अभी भी मुझे यकीन है कि मैं क्यों

em.createQuery(cq); 

यह काम कर पाने के लिखने की आवश्यकता नहीं कर रहा हूँ। कोई उपाय?

+0

क्या आप यह पता लगाने में सक्षम थे कि आपको 'em.createQuery (cq) क्यों जोड़ना है; '? धन्यवाद – Ittai

+0

अरे, यह वही है जो मुझे चाहिए ... bu मैं यह भी जानना चाहूंगा कि यह लाइन क्यों न हो! –

+0

मुझे संदेह है कि यह इस तथ्य से है कि 'रूट <12' का उपयोग इस भाग से 'रूट = cQuery.from (Brand.class) से किया जा रहा है;' और फिर दोनों के लिए उपयोग किया जाता है गिनती क्वेरी और पेजेड क्वेरी। AFAIK आपको 'रूट <>' ऑब्जेक्ट्स का उपयोग करके दो बार भविष्यवाणी करने की आवश्यकता है। दूसरा इस पंक्ति में छिपा हुआ है 'cq.select (builder.count (cq.from (brand.class)); '। वास्तव में 'em.createQuery (सीक्यू) क्यों; 'काम जो मुझे नहीं पता, आईएमओ इसे अपवाद फेंकना चाहिए। – Neilos

2

यदि आप अपने जेपीए-प्रदाता के रूप में हाइबरनेट का उपयोग कर रहे हैं तो projections पर विशेष रूप से Projections.rowCount() देखें।

आपको क्वेरी को दो बार निष्पादित करना पड़ सकता है, पहले गिनती प्राप्त करें और फिर परिणाम प्राप्त करें।

ध्यान दें कि सादा जेपीए के लिए आपको कुछ अन्य दृष्टिकोण की आवश्यकता हो सकती है।

+3

-1। ओपी ने स्पष्ट रूप से कहा कि वह "जेपीए मानदंड एपीआई" के संबंध में उत्तरदाताओं की तलाश में है, क्या आपको नहीं लगता कि आपका जवाब कुछ हद तक भ्रामक है? (हाइबरनेट अनुमानों को लागू करना ऐसा करने का तरीका है)। मैं यह कह रहा हूं क्योंकि जब मैंने इस सवाल पर ठोकर खाई तो मैंने आपका जवाब पहले देखा और यह मुझे सोचने में भ्रमित कर दिया कि यह तरीका है (विशेष रूप से जब आपके और अगले उत्तर के बीच एक जोड़ा था जो आपको एकमात्र दृश्यमान उत्तर देता था)। – Ittai

+0

@Ittai अच्छी तरह से, वह Hibernate का उल्लेख करता है और तदनुसार सवाल को ध्वजांकित करता है ... – Thomas

+0

मुझे लगता है कि जब आप सवाल पढ़ते हैं तो आप देखते हैं कि यह हाइबरनेट के बारे में नहीं है, यह सिर्फ इतना है कि आप कई बार देखते हैं कि लोग जवाब देते हैं कि वे क्या जवाब देते हैं लगता है कि ओपी की जरूरत है और ओपी अनुरोध क्या नहीं है। चूंकि यह एक ईमानदार गलती की तरह लगता है यदि आप अपना प्रश्न संपादित करेंगे तो मैं अपना वोट बदल दूंगा। – Ittai

14

आप गिनती का उपयोग क्यों नहीं करते?

CriteriaBuilder builder = em.getCriteriaBuilder(); 
CriteriaQuery<Long> cQuery = builder.createQuery(Long.class); 
Root<Brand> from = cQuery.from(Brand.class); 
CriteriaQuery<Long> select = cQuery.select(builder.count(from)); 
. 
. 
//Created many predicates and added to **Predicate[] pArray** 
. 
. 
select.where(pArray); 
// Added orderBy clause 
TypedQuery<Long> typedQuery = em.createQuery(select); 
typedQuery.setFirstResult(startIndex); 
//typedQuery.setMaxResults(pageSize); 
// here is the size of your query 
Long result = typedQuery.getSingleResult(); 
संबंधित मुद्दे