2012-02-08 13 views
8

मेरे पास 7 टेबल को पार करने वाली जटिल क्वेरी है और यह जानना है कि इसे हाइबरनेट के अंदर कैसे कार्यान्वित किया जाए।हाइबरनेट - एकाधिक टेबल्स से कॉम्प्लेक्स क्वेरी एक ऑब्जेक्ट

मेरे वर्तमान प्रयास session.createSQLQuery और मैं का उपयोग कर एक विशेष इकाई के लिए परिणाम नक्शा होगा क्वेरी बनाने के लिए है।

मैं कैसे करना है यह सुनिश्चित करें कि अतीत में के रूप में मैं केवल एक संस्था के लिए एक मेज के साथ काम किया है नहीं कर रहा हूँ। मुझे यह निर्दिष्ट करने की आवश्यकता होगी कि मैं एक जटिल क्वेरी का उपयोग करना चाहूंगा जो एकाधिक तालिकाओं को फैला सकता है? क्या यह केवल मेरे कोड में जाता है? मेरी hbm.xml फ़ाइल? मैं अपने वर्तमान प्रयास से परे कुछ भी नहीं सोच सकता।

String stringQuery = 
     "select WI.Customer_Id, CU.Card, CU.Code, "+ 
       "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ 
       "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ 
       "CO.City_Geo_Level, "+ 
       "CU.Address_id, CA.Name, "+ 
       "CU.Category_Id, "+ 
       "CU.Status, "+ 
       "Sum(MO.Charged_Points) as Charged_Points, "+ 
       "Sum(MO.Total_Money) as Total_Money, "+ 
       "Count(MO.id) as AmountTransWinner "+ 
     "from Promotions_Winner WI "+ 
     "join Customers CU "+ 
      "on WI.Customer_id = CU.id "+ 
     "join Personal_Info PI "+ 
      "on CU.Personal_Info_Id = PI.id "+ 
     "join Address AD "+ 
      "on CU.Address_Id = AD.id "+ 
     "join Countries CO "+ 
      "on AD.country_id = CO.id "+ 
     "join Campaigns CA "+ 
      "on CU.Campaign_Id = CA.id "+ 
     "join Movements MO "+ 
      "on WI.Movement_Id = MO.id "+ 
     "where WI.Promotion_Id = :pPromotionID "+ 
     "group by "+ 
      "WI.Customer_Id, CU.Card, CU.Fidely_Code, "+ 
      "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ 
      "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ 
      "CO.City_Geo_Level, "+ 
      "CU.Address_id, CA.Name, "+ 
      "CU.Category_Id, "+ 
      "CU.Status"; 
+0

http://stackoverflow.com/questions/21374550/fetching-data-from-multiple-tables-in-hibernate-and-storing-the-result-in-a-bean/21379254 देखें # 21379254 – Touchstone

उत्तर

5

आपने इस क्वेरी निष्पादित करने के लिए एसक्यूएल की जरूरत नहीं है:

यहाँ मेरी क्वेरी का एक उदाहरण है। एचक्यूएल ठीक करेगी। और ऐसी क्वेरी List<Object[]> लौटाती है, प्रत्येक Object[] परिणाम सेट की एक पंक्ति होती है। तो आपको इंडेक्स 0 पर ग्राहक आईडी, इंडेक्स 1 पर कार्ड मिलेगा। आपको केवल पंक्तियों को थ्रूग्न करना होगा और प्रत्येक पुनरावृत्ति पर अपने हल्के ऑब्जेक्ट का उदाहरण बनाना होगा।

http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#queryhql-select

+1

बजाय सूची और मैन्युअल रूप से अपने हल्के वस्तु आप 'उपयोग कर सकते हैं नए my.package.myLightWeightObject (t1.field1, t2.field2, t3.field3) का चयन बनाने' और बस सेटअप निर्माता myLightWeightObject के लिए पुनरावृत्ति उपयुक्त फ़ील्ड इस तरह हाइबरनेट आपके लिए सूची की बजाय सूची लौटाएगा। – digitaljoel

+0

जेबी निजेट, हाँ, मुझे पता है, लेकिन अगर मैं सूची का उपयोग करता हूं और भविष्य में, अन्य व्यक्ति वर्तमान क्षेत्रों के बीच एक नया क्षेत्र जोड़ता है, तो यह अब और काम नहीं करता है। मुझे डिजिटलजोएल विचार पसंद है, लेकिन मुझे समझ में नहीं आता कि यह कैसे करें। क्या आप थोड़ा और समझा सकते हैं? –

+0

हां। यदि वह कोड बदलने के बिना डेटाबेस टेबल बदलता है, तो यह या तो काम नहीं करेगा। यूनिट परीक्षण लागू करें, और जांचें कि क्वेरी यूनिट परीक्षणों में अपेक्षित कार्य करती है। मुझे नहीं पता कि मैं (या डिजिटलजोएल) उससे स्पष्ट कैसे हो सकता हूं। तुम क्या समझते हो क्या आपने कम से कम कुछ कोशिश की है? –

0

देखें तो जहाँ तक मैं देख सकता हूँ कि यह एक 7 टेबल के शामिल होने के लिए है। यदि आप हाइबरनेट का उपयोग कर रहे हैं तो आप इन तालिकाओं में से प्रत्येक को इकाइयों में मैप करेंगे और फिर @JoinColumn का उपयोग अपनी प्रत्येक निर्भरता पर मैप करने के लिए करेंगे। यह SQL क्वेरी का प्रकार है जो हाइबरनेट होता है जो घटना को रोकने के लिए होता है।

+0

लेकिन मेरे पास गिनती और सम फ़ील्ड हैं, –

+0

फिर आपको एक विधि के रूप में कुल ChargePoints() मिल जाएगा - यह आपका व्यवसाय तर्क होगा। इस तरह जो कुछ भी व्यक्ति को व्यक्तिगत राशि या गिनती की आवश्यकता होती है या जो कुछ भी इस क्वेरी को हर बार कॉल करने की आवश्यकता नहीं होती है। गिनती के लिए आप सचमुच सिर्फ List.size() को जो कुछ भी जोड़ते हैं, उसमें से किसी भी संग्रह में (0 से 32 रिश्तों के लिए) –

3

अंत में मैं इस कोड का उपयोग हल कर सकते हैं:

String stringQuery = 
       "select " + 
         "CU.Card as card, " + 
         "CU.Fidely_Code as fidelyCode, "+ 
         "PI.Identity_Card as identityCard, " + 
         "PI.Name as name, " + 
         "PI.Surname as surname, " + 
         "PI.Gender as gender, "+ 
         "AD.Zip as zip, " + 
         "AD.Geo_Lat as geo_lat, " + 
         "AD.Geo_Long as geo_long, "+ 
         "CO.City_Geo_Level as cityGeoLevel, "+ 
         "CA.Name as campaignName, "+ 
         "CU.Status as status, "+ 
         "Sum(MO.Charged_Points) as pointsCharged, "+ 
         "Sum(MO.Total_Money) as amountPurchase, "+ 
         "Count(MO.id) as amountTransWinner "+ 
       "from Promotions_Winner WI "+ 
       "join Customers CU "+ 
        "on WI.Customer_id = CU.id "+ 
       "join Personal_Info PI "+ 
        "on CU.Personal_Info_Id = PI.id "+ 
       "join Address AD "+ 
        "on CU.Address_Id = AD.id "+ 
       "join Countries CO "+ 
        "on AD.country_id = CO.id "+ 
       "join Campaigns CA "+ 
        "on CU.Campaign_Id = CA.id "+ 
       "join Movements MO "+ 
        "on WI.Movement_Id = MO.id "+ 
       "where WI.Promotion_Id = :pPromotionID "+ 
       "group by "+ 
        "WI.Customer_Id, CU.Card, CU.Fidely_Code, "+ 
        "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ 
        "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ 
        "CO.City_Geo_Level, "+ 
        "CU.Address_id, CA.Name, "+ 
        "CU.Category_Id, "+ 
        "CU.Status "; 

     //Query query = this.getSession().createSQLQuery(stringQuery).addEntity("", PromotionsWinnerLittle.class); 
     //Query query = this.getSession().createSQLQuery(stringQuery).setResultSetMapping("PromotionsWinnerLittle"); 
     Query query = this.getSession().createSQLQuery(stringQuery) 
      .addScalar("card", StandardBasicTypes.LONG) 
      .addScalar("fidelyCode", StandardBasicTypes.LONG) 
      .addScalar("identityCard", StandardBasicTypes.STRING) 
      .addScalar("name", StandardBasicTypes.STRING) 
      .addScalar("surname", StandardBasicTypes.STRING) 
      .addScalar("gender", StandardBasicTypes.STRING) 
      .addScalar("zip", StandardBasicTypes.STRING) 
      .addScalar("geo_lat", StandardBasicTypes.BIG_DECIMAL) 
      .addScalar("geo_long", StandardBasicTypes.BIG_DECIMAL) 
      .addScalar("cityGeoLevel", StandardBasicTypes.LONG) 
      .addScalar("campaignName", StandardBasicTypes.STRING) 
      .addScalar("status", StandardBasicTypes.LONG) 
      .addScalar("pointsCharged", StandardBasicTypes.BIG_DECIMAL) 
      .addScalar("amountPurchase", StandardBasicTypes.LONG) 
      .addScalar("amountTransWinner", StandardBasicTypes.LONG)    
      .setResultTransformer(Transformers.aliasToBean(PromotionsWinnerLittle.class)); 

     //Query query = this.getSession().createSQLQuery(stringQuery); 

     query = query.setLong("pPromotionID", promotionID); 

     List lista = query.list(); 

मैं बस जोड़ा करें और addScalar + पर भाग "के रूप में" setResultTransformer

+0

इस दृष्टिकोण में एक समस्या तब होती है जब आप डेटा को आदिम प्रकार के रूप में प्राप्त करते हैं और यदि आप चाहते हैं इस डेटा को किसी अन्य तालिका में लिखने के लिए जो उपयोगकर्ता परिभाषित प्रकारों की स्कीमा के साथ बनाया गया है, एक समस्या पैदा करने जा रहा है। – rakeeee

4

उनके ऐसा करने के दो तरीके हैं।

1. आप एक सूची वस्तु सरणी मिल जाएगा।

List<Object[]> 

यहां सरणी का एक तत्व आपकी क्वेरी की एक पंक्ति का प्रतिनिधित्व करता है।

2. आप एक हाइबरनेट सुविधा ResultTransformer उपयोग कर सकते हैं - अपनी क्वेरी के उत्पादन के लिए एक सरल वर्ग बनाएँ। - एक परिणाम ट्रांसफॉर्मर बनाएं।

पूर्व।

public class MyResultTransformer implements ResultTransformer { 


/* 
Method to convert to generic type list 
*/ 
    @Override 
    public List<Employee> transformList(List arg0) { 
     List<Employee> employees = new ArrayList<Employee>(); 
     for (Object employee : arg0) { 
      employees.add((Employee) employee); 
     } 
     return employees; 
    } 

    /* 
    Code to transform your query output to Object 
    */ 
    @Override 
    public Employee transformTuple(Object[] arg0, String[] arg1) { 
     System.out.println("MyResultTransformer.transformTuple()"); 
     Employee tempEmp = new Employee(); 
     tempEmp.setEmployee_id((BigInteger) arg0[0]); 
     return tempEmp; 
    } 
} 

- क्वेरी में ट्रांसफॉर्मर सेट करें।

Query query=session.createSQLQuery("SELECT * FROM employeedetail"); // You can use named query, SQL native also 
     query.setResultTransformer(new MyResultTransformer()); 
      List<Employee> employees=query.list(); 
संबंधित मुद्दे