जवाबों:
यहाँ 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});
यह ध्यान देने योग्य है कि distinct
HQL में distinct
कीवर्ड SQL में कीवर्ड से सीधे मैप नहीं होता है ।
यदि आप distinct
HQL में कीवर्ड का उपयोग करते हैं , तो कभी-कभी हाइबरनेट distinct
SQL कीवर्ड का उपयोग करेगा , लेकिन कुछ स्थितियों में यह परिणाम ट्रांसफार्मर का उपयोग करके अलग-अलग परिणाम देगा। उदाहरण के लिए जब आप इस तरह से बाहरी जुड़ाव का उपयोग कर रहे हैं:
select distinct o from Order o left join fetch o.lineItems
इस मामले में डुप्लिकेट को SQL स्तर पर फ़िल्टर करना संभव नहीं है, इसलिए हाइबरनेट SQL क्वेरी के प्रदर्शन के बादResultTransformer
डुप्लिकेट को फ़िल्टर करने के लिए उपयोग करता है ।
अगली बार कुछ ऐसा करें
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
आप Criteria.DISTINCT_ROOT_ENTITY
हाइबरनेट HQL क्वेरी के साथ भी उपयोग कर सकते हैं ।
उदाहरण:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
मुझे HQL प्रश्नों के साथ परिणाम ट्रांसफार्मर के साथ कुछ समस्याएं थीं। जब मैंने कोशिश की
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
यह काम नहीं किया। मुझे इस तरह मैन्युअल रूप से बदलना पड़ा:
final List found = trans.transformList(qry.list());
मानदंड एपीआई ट्रांसफार्मर के साथ बस ठीक काम किया।
मेरी मुख्य क्वेरी मॉडल में इस तरह दिखी:
@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;
}
मुझे उम्मीद है कि इससे मदद मिली! एक बार फिर, यह केवल तभी काम कर सकता है जब आप कोडिंग प्रथाओं का पालन कर रहे हैं जो सेवा, डाओ और मॉडल प्रकार की परियोजना को लागू करते हैं।
मान लीजिए कि आपके पास CUSTOMER_INFORMATION तालिका में एक ग्राहक इकाई है और आप ग्राहक के पहले नाम की सूची प्राप्त करना चाहते हैं। आप इसे प्राप्त करने के लिए स्निपेट के नीचे उपयोग कर सकते हैं।
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
मुझे उम्मीद है यह मदद करेगा। इसलिए यहां हम अलग-अलग कीवर्ड का उपयोग करने के बजाय समूह का उपयोग कर रहे हैं।
पहले भी मुझे अलग-अलग कीवर्ड का उपयोग करने में मुश्किल हुई, जब मैं इसे कई कॉलम में लागू करना चाहता हूं। उदाहरण के लिए मैं पहले firstName, lastName की सूची प्राप्त करना चाहता हूँ, तब समूह बस काम करेगा। मुझे इस मामले में विशिष्ट उपयोग करने में कठिनाई हुई।
मुझे डिस्टि्रक्ट फ़ील्ड का उपयोग करने के लिए हाइबरनेट क्वेरी लैंग्वेज का उत्तर मिला है। आप 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 ।
सब ठीक हो सकता है
आप मानदंड बिल्डर में आप इस तरह से अलग कीवर्ड कर सकते हैं।
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));
और अपने मॉडल क्लास में फील्ड कंस्ट्रक्टर बनाएं।
यदि आपको अपने चुनिंदा कथन में एक कस्टम DTO के लिए नए कीवर्ड का उपयोग करने की आवश्यकता है और अलग-अलग तत्वों की आवश्यकता है , तो नए के बाहर नए का उपयोग करें जैसे कि-
select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...