2009-07-01 5 views
9

के माध्यम से हाइबरनेट मानदंडों का खुलासा यह कार्यान्वयन प्रश्न से अधिक डिज़ाइन है और यह मेरे साथ लंबे समय तक सहन करने जा रहा है। यह सबसे अच्छा एक उदाहरण के साथ समझाया है: सेवा एपीआई

चलो कहते हैं कि मैं एक व्यावसायिक इकाई उत्पाद बुलाया गुणों का एक गुच्छा (नाम, कीमत, विक्रेता, आदि ...) के साथ करते हैं।

यह एक इंटरफेस (उत्पाद) और कार्यान्वयन (ProductImpl, हाइबरनेट में मैप) के साथ ही बुनियादी CRUD सेवा इंटरफ़ेस (ProductService) और कार्यान्वयन (ProductServiceImpl) का प्रतिनिधित्व करती है।
उत्पाद और उत्पाद सेवा एपीआई के रूप में उजागर हैं, उनके कार्यान्वयन नहीं हैं।

मैं एक सूची findProducts (QueryCriteria मापदंड) को विधि ProductService कि दिए गए मापदंड संतोषजनक उत्पादों की एक सूची वापस होगा जोड़ना चाहते हैं। आवश्यकताएँ हैं: प्रत्यक्ष उत्पाद गुण (जैसे product.price gt 50.0)

  • क्वेरी संघ द्वारा (जैसे product.vendor.name = "Oracle")
  • क्रमबद्ध परिणाम (जैसे order by product.vendor.name desc, product.price asc") द्वारा

    1. क्वेरी
    2. अतिरिक्त फ़िल्टर लागू करें। उपर्युक्त 3 आइटमों के विपरीत जो सभी एपीआई क्लाइंट द्वारा निर्दिष्ट हैं, अतिरिक्त फ़िल्टर क्लाइंट की पहचान के आधार पर सेवा द्वारा लागू किए जा सकते हैं (उदाहरण के लिए क्लाइंट इस विधि का आह्वान कर सकता है केवल दिए गए विक्रेता द्वारा उत्पादित उत्पादों को देखकर सीमित हो सकता है)। इस तरह के फिल्टर ग्राहक द्वारा निर्दिष्ट मापदंड से प्राथमिकता दी जाती है (जैसे फिल्टर product.vendor.name = "Microsoft" पर सेट है, में क्वेरी (2) ऊपर खाली परिणाम सेट प्रस्तुत करना चाहिए।

    सवाल है, इसलिए, क्या करना चाहिए QueryCriteria है इस तरह के एक विधि द्वारा उपयोग इंटरफ़ेस की तरह देखो मैं 3 समाधान के बारे में सोच सकते हैं और मुझे पसंद नहीं है या तो उनमें से एक:।

    • ग्राहकों HQL सीधे (साथ "कहाँ" खंड शुरू) निर्दिष्ट करने के लिए अनुमति दें यह वह जगह है सबसे सरल समाधान, लेकिन सबसे समस्याग्रस्त सुरक्षा-वार भी। यह मानते हुए कि फ़िल्टर (ऊपर # 4) सरल हैं और हाइबरनेट के सत्र फ़िल्टर के माध्यम से लागू करने के लिए पर्याप्त है, एचक्यूएल को अभी भी कम से कम पार्स किया जाना चाहिए - सुनिश्चित करें कि क्वेरी पैरामीटर पैरामीटर के रूप में निर्दिष्ट हैं और इनलाइन नहीं हैं।
    • उपयोग बारीकी QueryCriteria के स्थान पर हाइबरनेट के DetachedCriteria लपेटा। "पतला लपेटा" क्योंकि क्लाइंट को डिटेक्टेडक्रिटिया बनाने की अनुमति नहीं दी जा सकती है, इसके लिए सीधे मैप किए गए इकाई को नियंत्रित करने का कोई तरीका नहीं होगा। इसके अलावा, यह कुछ प्रश्नों के लिए एचक्यूएल के रूप में लचीला नहीं होगा, मानदंड एपीआई के माध्यम से आसानी से (या बिल्कुल) स्पष्ट नहीं है। एचक्यूएल दृष्टिकोण के साथ, फ़िल्टर (ऊपर # 4) हाइबरनेट सत्र फ़िल्टर तक सीमित होंगे।
    • अपना खुद का लिखें QueryCriteria इंटरफ़ेस/कार्यान्वयन जो दृश्यों के पीछे या तो पृथकक्रिटिया या एचक्यूएल बना देगा। शायद सबसे लचीला समाधान होने पर, इसे मानदंड एपीआई से बहुत सारे कोड को डुप्लिकेट करना होगा जो आदर्श से कम लगता है।

    उपर्युक्त दृष्टिकोण की वैधता पर कोई टिप्पणी या उंगलियों को पार किया गया - सरल सुरुचिपूर्ण समाधान जो मेरे साथ नहीं हुआ, उसकी अत्यधिक सराहना की जाएगी।

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

  • +0

    ऐसा लगता है कि यह प्रश्न दो महीने तक रहा है; मैं उत्सुक हूँ कि आप किस पर बस गए? मुझे लगता है कि मैंने # 3 ले लिया होगा, "अपना खुद का लिखें ..." दृष्टिकोण, और उपयोग के आधार पर उत्पाद सेवा/मानदंड API पर पूछे जाने वाले गुणों के टुकड़ों को "फ़्लैट" करने की कोशिश की। – RMorrisey

    +0

    @RMorrisey - मैंने अपने समाधान का वर्णन करने वाला एक जवाब जोड़ा है। – ChssPly76

    उत्तर

    2

    मैंने जो वास्तविक समाधान लागू किया है वह एक संकर दृष्टिकोण का उपयोग करता है।

    public List<Entity> findEntities(String queryName, QueryParameters parameters); 
    

    जहां QueryParameters के लिए एक सुविधा वर्ग है:

    तरीके का उपयोग अच्छी तरह से परिभाषित प्रश्नों (जैसे तरीकों कि अन्य सेवाओं द्वारा आंतरिक रूप से उपयोग किया जाता है, पूर्व-निर्धारित रिपोर्ट, आदि) HibernateTemplate के findBy तरीकों के समान हस्ताक्षर है नामित पैरामीटर को स्पष्ट रूप से निर्दिष्ट करना या उन्हें एक बीन से लेना। नमूना उपयोग है:

    List<Product> products = findProducts("latestUpdates", 
    new QueryParameters() 
        .add("vendor", "Oracle") 
        .add("price", "50.0") 
    ); 
    

    या

    List<Product> products = findProducts("latestUpdates", 
    new QueryParameters(product, "vendor", "price")); 
    

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


    तरीके यूआई के संपर्क में हैं या नहीं तो Hibernate-Generic-DAO परियोजना से अधिक गतिशील उपयोग Search इंटरफेस होने की जरूरत है कि। यह कुछ हद तक हाइबरनेट के DetachedCriteria के समान है, लेकिन कई फायदे हैं:

    1. यह विशेष इकाई से बंधा जा रहा है बिना बनाया जा सकता है।यह मेरे लिए एक बड़ा सौदा है क्योंकि इकाई इंटरफ़ेस (उपयोगकर्ताओं के लिए दृश्यमान एपीआई का हिस्सा) और कार्यान्वयन (हाइबरनेट में मैप किए गए पीओजेओ) दो अलग-अलग वर्ग हैं और कार्यान्वयन समय पर उपयोगकर्ता के लिए कार्यान्वयन उपलब्ध नहीं है।

    2. यह एक अच्छी तरह से खुला खुला इंटरफ़ेस है; डिटेक्टेड क्राइटरिया के विपरीत, जिसमें से कुछ भी निकालना लगभग असंभव है (हाँ, मुझे पता है कि डीसी इसके लिए डिज़ाइन नहीं किया गया था, लेकिन फिर भी)

    3. अंतर्निहित अंकन/परिणाम अन्य छोटी नब्बे के कुल गिनती/गुच्छा के साथ।

    4. हाइबरनेट के लिए कोई स्पष्ट संबंध नहीं है (हालांकि मैं व्यक्तिगत रूप से इस बारे में वास्तव में परवाह नहीं करता हूं; मैं अचानक हाइबरनेट छोड़ने वाला नहीं हूं और कल ग्रहण के साथ जाऊंगा); दोनों हाइबरनेट और जेनेरिक जेपीए कार्यान्वयन उपलब्ध हैं।

    फ़िल्टर पक्ष सेवा पर खोज में जोड़ा जा सकता है; वह तब होता है जब इकाई वर्ग भी निर्दिष्ट किया जाता है। अमान्य संपत्ति का नाम निर्दिष्ट होने पर केवल एक चीज गायब है, क्लाइंट पक्ष पर त्वरित विफल है और इसे अपना स्वयं का आईएसर्च/IMutableSearch कार्यान्वयन लिखकर हल किया जा सकता है लेकिन मुझे अभी तक यह नहीं मिला।

    0

    ऐसे कार्यान्वयन विवरणों का खुलासा करना कभी भी अच्छा विचार नहीं है। आप वहां से उस पुस्तकालय से बंधे हैं। इससे भी बदतर, लाइब्रेरी का कोई भी एपीआई परिवर्तन आपके एपीआई को आपके सेवा में बदल देगा। किसी भी सुरक्षा विचार पीछे छोड़ दिया गया है ...

    मानदंड में उपयोग किए जाने वाले बीन संपत्ति नामों के बारे में क्या है (संपत्ति का नाम तीन गुना, कम, बराबर और अधिक मूल्य के साथ enum)। अपने मॉडल पर एक बीन रैपर के साथ, आप इसे एक हाइबरनेट मानदंड में बदल सकते हैं।

    मॉडल परिवर्तन के बाद इस संपत्ति के नाम को नए संस्करण में बदलना भी संभव होगा।

    +1

    मुझे एहसास है कि आप सबकुछ अमूर्त कर सकते हैं लेकिन कहीं एक रेखा है - मुझे पूरा यकीन है कि मैं ओआरएम परतों को स्विच नहीं कर रहा हूं और मुझे संदेह है कि हाइबरनेट एपीआई निकट भविष्य में पीछे-असंगत तरीके से बदल जाएगा। उस ने कहा, मैंने ऊपर दिए गए 3 प्रस्तावित समाधानों में सीधे हाइबरनेट एपीआई को उजागर करने का सुझाव नहीं दिया था। सुनिश्चित नहीं है कि आप "मॉडल बीन रैपर" से क्या मतलब रखते हैं लेकिन संपत्ति/तुलना/मूल्य सिर्फ एक साधारण मामला है। एक बार जब आप एंड्रॉइड/ओआरएस, संपत्ति-से-संपत्ति तुलना, संग्रह इत्यादि जोड़ते हैं ... आप संपूर्ण मानदंड API को फिर से लिखना समाप्त कर देंगे। – ChssPly76

    1

    हम्म - दिलचस्प सवाल।

    इसे सोचने के बाद, अपना खुद का मानदंड इंटरफ़ेस लिखना संभवतः जाने का तरीका है। यह आपको कार्यान्वयन से नहीं जोड़ देगा और सुरक्षा चिंताओं को कम करेगा।

    इस बात पर निर्भर करता है कि कितने ऑब्जेक्ट शामिल हैं, उत्पादों के पूरे सेट को लौटने पर विचार किया जाता है (आवश्यक फ़िल्टर के साथ) तो अंतिम उपयोगकर्ता लैम्बडाज या इसी तरह के फ़िल्टर के साथ फ़िल्टर लागू करता है। देखें:

    http://code.google.com/p/lambdaj/

    +0

    धन्यवाद। LambdaJ पोस्ट-मानदंड फ़िल्टर (ऊपर # 4) लागू करने के लिए एक दिलचस्प दृष्टिकोण है जिसे हाइबरनेट फ़िल्टर के माध्यम से व्यक्त नहीं किया जा सकता है। लेकिन जैसा कि आपने कहा था, वह डेटा वॉल्यूम के कारण खोजने() विधि में मदद नहीं करेगा। – ChssPly76

    0

    हाइबरनेट एक निम्न स्तर के बुनियादी ढांचे ढांचा है, और के रूप में ऐसी पर्दे के पीछे छिपा रहना चाहिए। अगर अगले महीने किसी एप्लिकेशन के लिए आपके एप्लिकेशन को किसी अन्य ओआरएम फ्रेमवर्क पर स्विच करने की आवश्यकता है, तो आपका एपीआई बेकार होगा। एक ही आवेदन के भीतर परतों के बीच भी Encapsulation, महत्वपूर्ण रूप से महत्वपूर्ण है।

    यह सब कहकर, मुझे लगता है कि आपकी विधि को खोज करने के लिए आवश्यक जानकारी का एक अमूर्त होना चाहिए। मैं आपको Product के फ़ील्ड का एक enum बनाने की सलाह देता हूं, और प्रतिबंध के एक या दो साधारण संस्करणों को लागू करता हूं।

    विधि के पैरामीटर समानता प्रतिबंधों की एक सूची हो सकते हैं, सापेक्ष प्रतिबंधों की एक और सूची और निश्चित रूप से एक ऑर्डर इंडिकेटर (एनम मूल्यों में से एक प्लस एसी/अवर के लिए ध्वज) हो सकता है।

    यह सिर्फ एक सामान्य दिशा है, मुझे आशा है कि मैं अपनी बात स्पष्ट कर दिया = 8-)

    +0

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

    2

    विकल्प: यदि यह अपने एपीआई का विस्तार करने के लिए संभव है, मैं अपने एपीआई "अमीर" करने का सुझाव - अपनी सेवा को और अधिक प्राकृतिक बनाने के लिए नीचे दी गई कुछ विधियों को जोड़ना।यह आपके एपीआई को फुलाए हुए लगने के बिना बड़ा बनाने में मुश्किल हो सकता है, लेकिन यदि आप एक समान नामकरण योजना का पालन करते हैं तो यह उपयोग करने के लिए प्राकृतिक प्रतीत होता है।

    productService.findProductsByName("Widget") 
    productService.findProductsByName(STARTS_WITH,"Widg") 
    productService.findProductsByVendorName("Oracle") 
    productService.findProductsByPrice(OVER,50) 
    

    परिणाम (अनेक प्रतिबंध को लागू करने) के संयोजन के बाद वे परिणाम CollectionUtils और विधेय का उपयोग करके सेट प्राप्त ग्राहकों करने के लिए कुछ के रूप में छोड़ा जा सकता है। आप अपने एपीआई के उपभोक्ताओं के लिए कुछ अच्छे भविष्यवाणियों को भी अच्छे बना सकते हैं। CollectionUtils.select() मजेदार है।

    विकल्प दो: यदि एपीआई का विस्तार करना संभव नहीं है, तो आपकी तीसरी गोली वह है जिसे मैं साथ जाऊंगा।

    • मेरे अपने QueryCriteria इंटरफ़ेस/कार्यान्वयन जो पर्दे के पीछे या तो DetachedCriteria या HQL बनेगी ...

    तुम कुछ का उपयोग कर नामकरण करने के लिए एक डीएसएल शैली दृष्टिकोण लागू करने का प्रयास कर सकता है लिखें चीज़ों को और अधिक पठनीय और प्राकृतिक ध्वनि बनाने के लिए बिल्डर पैटर्न के समान। , दो दृष्टिकोण कम्बाइन एक अमीर एपीआई के साथ एक प्रतिबंध शैली मापदंड प्रदान:

    Product.Restriction restriction = new Product.Restriction().name("Widget").vendor("Oracle").price(OVER,50)); 
    productService.findProducts(restriction); 
    

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

    +0

    उत्तर के लिए धन्यवाद। जबकि समृद्ध एपीआई "ज्ञात" ग्राहकों (उदाहरण के लिए अनुमानित/ज्ञात प्रश्नों वाली अन्य सेवाओं) के लिए बहुत अच्छा काम करता है, यह यूआई के लिए काम नहीं करेगा जहां मानदंड/सॉर्ट ऑर्डर मनमाने ढंग से उपयोगकर्ताओं द्वारा निर्दिष्ट किया जाता है। एक बार एसोसिएशन/संग्रह शामिल होने के बाद क्यूबीई-स्टाइल प्रश्न जटिलता में पूर्ण डिटेक्टेडक्रिटिया एपीआई से तुरंत संपर्क करते हैं ताकि यह जवाब भी न हो। तो यहां पहिया को फिर से शुरू करने पर सर्वसम्मति प्रतीत होती है, हुह? मुझे वास्तव में यह पसंद नहीं है :-( – ChssPly76

    +0

    शायद मूल्यांकन करें कि ग्राहकों को पूरी तरह से सबकुछ चाहिए या नहीं। इसी तरह की स्थितियों में, उदाहरण के लिए, मैं उपभोग करने वाले अनुप्रयोगों को डिफ़ॉल्ट क्रम क्रम में परिणाम प्रदान करता हूं, और यदि वे परिणाम अलग-अलग क्रमबद्ध करना चाहते हैं तो मैं वैकल्पिक प्रकार के प्रदर्शन के लिए उन्हें छोड़ दें। – dustmachine

    0

    मुझे लगता है कि query by example वास्तव में यहां अच्छा काम करेगा।

    +0

    मैं असहमत हूं। हाइबरनेट क्यूबीई _extremely_ सीमित हैं - केवल "ऑपरेशंस"/"जैसे" ऑपरेशंस, कोई शर्त समूह नहीं, आदि ... और अपना स्वयं का कार्यान्वयन प्रभावी ढंग से लिखना जैसा ही है DetachedCriteria का अपना संस्करण – ChssPly76

    संबंधित मुद्दे