2009-01-08 5 views
26

क्या किसी को पता है कि Grails के माध्यम से एक एसक्यूएल दृश्य तक पहुंचने का सबसे अच्छा तरीका क्या है (या यदि यह भी संभव है)? ऐसा करने का एक स्पष्ट तरीका यह है कि दृश्य के पंक्तियों का संग्रह चुनने के लिए executeQuery का उपयोग करना होगा, जिसे हम डोमेन ऑब्जेक्ट्स की सूची के रूप में नहीं मानेंगे। हालांकि, यहां तक ​​कि इस मामले में यह स्पष्ट नहीं है कि कौन सी डोमेन क्लास executeQuery को चलाने के लिए है, क्योंकि वास्तव में हम पूरी तरह से असंबंधित इकाई (दृश्य) के विरुद्ध क्वेरी चलाने के लिए केवल उस डोमेन क्लास का उपयोग कर रहे हैं।Grails में SQL/डेटाबेस दृश्य

क्या इसे देखने के लिए एक डोमेन क्लास बनाना पसंद किया जाएगा और फिर हम उस डोमेन क्लास के विरुद्ध सूची() का उपयोग कर सकते हैं? ऐसा लगता है कि इसके साथ समस्याएं हो सकती हैं क्योंकि Grails शायद किसी भी डोमेन वर्ग की तालिका स्कीमा डालने, अपडेट करने, हटाने और संशोधित करने में सक्षम होने की अपेक्षा करता है।

[संपादित करें:
यहाँ सवाल को का पालन करें: Grails Domain Class without ID field or with partially NULL composite field

उत्तर

34

आप जो एक दृश्य के लिए बेहतर तरीका (IMO) तक पहुँचने के मामले में है Grails में सादे एसक्यूएल का उपयोग कर सकते हैं: में

उदाहरण के लिए आपके नियंत्रक:

import groovy.sql.Sql 

class MyFancySqlController { 

    def dataSource // the Spring-Bean "dataSource" is auto-injected 

    def list = { 
     def db = new Sql(dataSource) // Create a new instance of groovy.sql.Sql with the DB of the Grails app 

     def result = db.rows("SELECT foo, bar FROM my_view") // Perform the query 

     [ result: result ] // return the results as model 
    } 

} 

और देखने हिस्सा:

<g:each in="${result}"> 
    <tr> 
     <td>${it.foo}</td> 
     <td>${it.bar}</td> 
    </tr> 
</g:each> 

मुझे आशा है कि स्रोत आत्म-व्याख्यात्मक है। Documentation can be found here

+0

यह बहुत अच्छा लग रहा है, धन्यवाद! मैं एक प्रकार का "वर्चुअल" डोमेन क्लास का उपयोग करना पसंद करूंगा, लेकिन जैसा कि मैंने कहा था कि मुझे सच में संदेह है कि इस तरह की स्थिति में भी संभव है। –

+0

साल बाद, अभी भी काम करता है (Grails 2.0)। जब कोई प्रश्न मूल एसक्यूएल की मांग करता है तो अच्छा हाइबरनेट बच निकलता है। – virtualeyes

2

एक डोमेन क्लास को देखने के लिए मानचित्र करना बिल्कुल संभव है, बस इसे नियमित तालिका की तरह व्यवहार करें। मुझे लगता है कि Grails कुछ लॉग संदेशों को प्रिंट करेगा, क्योंकि वे आवेषण, हटाना इत्यादि करने में सक्षम नहीं हैं, लेकिन यह किसी भी त्रुटि को फेंक नहीं देगा जबतक कि आप वास्तव में डोमेन क्लास के साथ क्वेरी के अलावा कुछ और करने का प्रयास नहीं करते हैं।

+0

यह आमतौर पर काम करता प्रतीत होता है, लेकिन मुझे कुछ मामलों में कुछ समस्याएं थीं। यदि आप इसे एक शॉट देना चाहते हैं तो ऊपर दिए गए प्रश्न में जोड़े गए अतिरिक्त लिंक को देखें। धन्यवाद! –

4

आप अपने डोमेन वर्ग मैपिंग में इस डाल सकते हैं: वैसे भी

static mapping = { 
    cache 'read-only' 
} 

लेकिन मुझे यकीन है कि अगर यह मदद करता है हाइबरनेट समझते हैं कि यह एक दृश्य है नहीं कर रहा हूँ ... http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-cache-readonly

, हम डेटाबेस एक विचार का उपयोग हमारे वर्तमान प्रोजेक्ट में grails डोमेन क्लासेस के रूप में बहुत कुछ, क्योंकि एचक्यूएल गधे में दर्द है और तालिकाओं में शामिल होने के लिए एसक्यूएल का उपयोग करना आसान है।

हालांकि आपको एक चीज के बारे में सावधान रहने की आवश्यकता है, प्रश्नों के हाइबरनेट बैचिंग (और पूरे फ्लश व्यवसाय) हैं। यदि आप किसी तालिका में कुछ डालते हैं, और फिर उसी लेनदेन में आप उस दृश्य पर क्लिक करते हैं जो उस तालिका पर निर्भर करता है, तो आपको नवीनतम पंक्तियां नहीं मिलेंगी। ऐसा इसलिए है क्योंकि हाइबरनेट ने वास्तव में पंक्तियों को अभी तक नहीं डाला होगा, जबकि यदि आपने उस तालिका को चुना है जिसमें आपने पंक्तियां डाली हैं, तो हाइबरनेट ने यह पता लगाया होगा कि आपको अपने चयन का परिणाम देने से पहले अपने लंबित प्रश्नों को फ़्लश करने की आवश्यकता है।

एक समाधान (flush:true) एक डोमेन उदाहरण सहेजते समय आपको पता है कि आपको उसी लेनदेन में उसके बाद एक दृश्य को पढ़ने की आवश्यकता होगी।

हालांकि यह अच्छा होगा कि हाइबरनेट को यह बताने का कोई तरीका है कि एक दृश्य/डोमेन अन्य डोमेन वर्गों पर निर्भर करता है, ताकि हाइबरनेट फ़्लशिंग अच्छी तरह से काम करे।

+0

विचारों से निपटने के दौरान फ्लशिंग के बारे में बहुत अच्छी बात है। –