आप एचक्यूएल में एक विशिष्ट क्वेरी कैसे बनाते हैं


100

क्या HQL में एक विशिष्ट क्वेरी बनाने का एक तरीका है। या तो "अलग" कीवर्ड या किसी अन्य विधि का उपयोग करके। मुझे यकीन नहीं है कि अगर HQL के लिए एक वैध कुंजीवर्क है, लेकिन मैं SQL कीवर्ड "भिन्न" के बराबर HQL की तलाश कर रहा हूं।

जवाबों:


124

यहाँ hql का एक स्निपेट है जिसका हम उपयोग करते हैं। (पहचान की रक्षा के लिए नाम बदल दिए गए हैं)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});

मैंने केवल MySQL के साथ हाइबरनेट का उपयोग किया था - यह सुनिश्चित नहीं किया कि mssql समस्या से कैसे निपटें।
पैर

56

यह ध्यान देने योग्य है कि distinctHQL में distinctकीवर्ड SQL में कीवर्ड से सीधे मैप नहीं होता है ।

यदि आप distinctHQL में कीवर्ड का उपयोग करते हैं , तो कभी-कभी हाइबरनेट distinctSQL कीवर्ड का उपयोग करेगा , लेकिन कुछ स्थितियों में यह परिणाम ट्रांसफार्मर का उपयोग करके अलग-अलग परिणाम देगा। उदाहरण के लिए जब आप इस तरह से बाहरी जुड़ाव का उपयोग कर रहे हैं:

select distinct o from Order o left join fetch o.lineItems

इस मामले में डुप्लिकेट को SQL स्तर पर फ़िल्टर करना संभव नहीं है, इसलिए हाइबरनेट SQL क्वेरी के प्रदर्शन के बादResultTransformer डुप्लिकेट को फ़िल्टर करने के लिए उपयोग करता है ।


1

16

अगली बार कुछ ऐसा करें

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();

यह उप-योग है: डेटाबेस स्तर पर पुनरावृत्ति को छोड़ने के बजाय, यह डेटाबेस से डेटा को पुनरावृत्ति और सभी के साथ मेमोरी में खींच लेगा, और फिर बाद में दोहराव को छोड़ देगा; डेटा कितनी बार दोहराता है, इसके आधार पर, I / O संचालन को काफी बढ़ा सकता है।
हेरोल्डो_को

9

आप Criteria.DISTINCT_ROOT_ENTITYहाइबरनेट HQL क्वेरी के साथ भी उपयोग कर सकते हैं ।

उदाहरण:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();

1
यह उप-योग है: डेटाबेस स्तर पर पुनरावृत्ति को छोड़ने के बजाय, यह डेटाबेस से डेटा को पुनरावृत्ति और सभी के साथ मेमोरी में खींच लेगा, और फिर बाद में दोहराव को छोड़ देगा; डेटा कितनी बार दोहराता है, इसके आधार पर, I / O संचालन को काफी बढ़ा सकता है।
हेरोल्डो_को

4

मुझे HQL प्रश्नों के साथ परिणाम ट्रांसफार्मर के साथ कुछ समस्याएं थीं। जब मैंने कोशिश की

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

यह काम नहीं किया। मुझे इस तरह मैन्युअल रूप से बदलना पड़ा:

final List found = trans.transformList(qry.list());

मानदंड एपीआई ट्रांसफार्मर के साथ बस ठीक काम किया।


10k को पाने के लिए: (:
टाइममज़

3

मेरी मुख्य क्वेरी मॉडल में इस तरह दिखी:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

और मुझे अभी भी वह नहीं मिल रहा था जिसे मैं "अलग" परिणाम मानता था। वे मेज पर एक प्राथमिक कुंजी संयोजन के आधार पर अलग-अलग थे।

इसलिए DaoImplमैंने एक पंक्ति में बदलाव किया और "विशिष्ट" रिटर्न प्राप्त करना चाहता था जो मुझे चाहिए था। एक उदाहरण होगा ४०० बार देखने के बजाय मैं अब इसे एक बार देखूंगा। यह कोड मैंने यहां जोड़ा है DaoImpl:

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

मुझे उम्मीद है कि इससे मदद मिली! एक बार फिर, यह केवल तभी काम कर सकता है जब आप कोडिंग प्रथाओं का पालन कर रहे हैं जो सेवा, डाओ और मॉडल प्रकार की परियोजना को लागू करते हैं।


2

मान लीजिए कि आपके पास CUSTOMER_INFORMATION तालिका में एक ग्राहक इकाई है और आप ग्राहक के पहले नाम की सूची प्राप्त करना चाहते हैं। आप इसे प्राप्त करने के लिए स्निपेट के नीचे उपयोग कर सकते हैं।

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

मुझे उम्मीद है यह मदद करेगा। इसलिए यहां हम अलग-अलग कीवर्ड का उपयोग करने के बजाय समूह का उपयोग कर रहे हैं।

पहले भी मुझे अलग-अलग कीवर्ड का उपयोग करने में मुश्किल हुई, जब मैं इसे कई कॉलम में लागू करना चाहता हूं। उदाहरण के लिए मैं पहले firstName, lastName की सूची प्राप्त करना चाहता हूँ, तब समूह बस काम करेगा। मुझे इस मामले में विशिष्ट उपयोग करने में कठिनाई हुई।


1

मुझे डिस्टि्रक्ट फ़ील्ड का उपयोग करने के लिए हाइबरनेट क्वेरी लैंग्वेज का उत्तर मिला है। आप FLECT_ROUTE * से * SELECT DISTINCT (TO_CITY) का उपयोग कर सकते हैं। यदि आप SQL क्वेरी का उपयोग करते हैं , तो यह स्ट्रिंग सूची लौटाता है। आप इसे एंटिटी क्लास द्वारा रिटर्न मान का उपयोग नहीं कर सकते। तो उस प्रकार की समस्या को हल करने के लिए उत्तर SQL के साथ HQL का उपयोग करें ।

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

से एसक्यूएल क्वेरी बयान यह DISTINCT ROUTE_ID और एक सूची के रूप में इनपुट मिला है। और IN में IN (सूची) से अलग TO_CITY फ़िल्टर करें।

रिटर्न टाइप एंटिटी बीन टाइप है। तो आप इसे AJAX में कर सकते हैं जैसे कि AutoComplement

सब ठीक हो सकता है


1

आप मानदंड बिल्डर में आप इस तरह से अलग कीवर्ड कर सकते हैं।

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

और अपने मॉडल क्लास में फील्ड कंस्ट्रक्टर बनाएं।


0

यदि आपको अपने चुनिंदा कथन में एक कस्टम DTO के लिए नए कीवर्ड का उपयोग करने की आवश्यकता है और अलग-अलग तत्वों की आवश्यकता है , तो नए के बाहर नए का उपयोग करें जैसे कि-

select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...

0

आप डिस्टिंक्ट के बजाय बस ग्रुप बी जोड़ सकते हैं

@Query(value = "from someTableEntity where entityCode in :entityCode" +
            " group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.