2013-03-05 6 views
10

मैंने एक नई परियोजना के लिए Mybatis को आजमाने और उपयोग करने का निर्णय लिया है। मैं एसक्यूएल के साथ सौभाग्य से परिचित हूं, और हाल ही में मुझे हाइबरनेट के साथ कुछ बुरे अनुभव हुए हैं इसलिए मैं डीएओ के लिए एक और निम्न स्तर के दृष्टिकोण की तलाश में हूं।माइबेटिस के साथ संग्रह सहेजना/अद्यतन करना, सामान्य अभ्यास क्या है?

एक चीज़ को छोड़कर काफी अच्छा लगता है, और यह संग्रहों को संभालने वाला है।

मेरे पास दो पीओजेओ, समूह और उपयोगकर्ता हैं, जो कई से अधिक हैं। मैंने एक डिज़ाइन दर्शन पर निर्णय लिया है कि एक पीओजेओ जिसमें संग्रह है, केवल सहेजे जाने पर तालिकाओं के बीच एम-एम संबंध अपडेट करना चाहिए। इसलिए, उदाहरण के लिए, जब मैं एक समूह ऑब्जेक्ट को सहेजता हूं जिसमें उपयोगकर्ताओं का संग्रह होता है, तो डिज़ाइन दर्शन यह बताता है कि उपयोगकर्ताओं को पहले से ही सहेजा जाना चाहिए, और मुझे केवल डेटाबेस में समूह और समूह_यूज़र संबंध को सहेजना होगा।

हां, इंटरफ़ेस में saveGroup समारोह के लिए, मैं mybatis के लिए इस XML मैपिंग कर दिया है:

<insert id="saveGroup" keyColumn="id" 
    parameterType="se.myapp.domain.Group"> 
    <choose> 
     <when test="id == null"> 
     INSERT INTO myapp_group (name, description) 
     VALUES 
     (#{username}, #{password}); 
     </when> 
     <otherwise> 
     UPDATE myapp_group set name=#{name}, description=#{description} 
     where id=#{id}; 
     </otherwise> 
    </choose> 

    <if test="users != null"> 
     create temporary table tmpnewgroups (group_id integer, user_id integer); 

     insert into tmpnewgroups (group_id, user_id) values (
     <foreach collection="users" item="user" open="" close="" separator="),()"> 
      #{id},#{user.id} 
     </foreach> 
     ); 

     insert into myapp_user_group(group_id, user_id) 
     select tmp.group_id, tmp.user_id 
     from tmpnewgroups tmp 
     left outer join myapp_user_group ug 
      on ug.group_id = tmp.group_id and ug.user_id = tmp.user_id 
     where ug.group_id is null; 

     delete from myapp_user_group 
     where group_id = #{id} and user_id not in (select user_id from tmpnewgroups); 
    </if> 

</insert> 

के रूप में इरादा यह कार्य करता है (सम्मिलित/समूह अपडेट हो जाता है, संबंधों के रूप में उपयोगकर्ताओं के संग्रह की बचत होती है डेटाबेस में)। लेकिन मुझे सच में नहीं लगता कि यह सबसे अच्छा अभ्यास है। आवेदन किया जाता है ताकि यदि आवश्यक हो तो मैं हाइबरनेट पर स्विच कर सकता हूं, इसलिए संग्रह को सहेजने के लिए तर्क डेटाबेस स्तर में अधिमानतः होना चाहिए। क्या माइबेटिस में कुछ "जादू" है कि मुझे इस बात से अवगत नहीं है कि इस तरह के संचालन को सुव्यवस्थित कर सकते हैं?

इस पर सुधार करने के तरीके पर कोई विचार? या क्या मुझे एप्लिकेशन डिज़ाइन पर पुनर्विचार करना चाहिए और मॉडल में संग्रहों को संभालना चाहिए?

+0

कई लोगों का वर्णन करने के लिए ' 'और इसके' ' का उपयोग करने में कोई समस्या थी: कई रिश्ते? – Gus

+0

अच्छी तरह से परिणाम परिणाम डेटा प्राप्त करने के लिए डेटा प्राप्त करने के लिए हैं। संग्रह प्राप्त करना कोई समस्या नहीं है, यह उन्हें बचा रहा है कि मुझे बोझिल लगता है। – Dytut

+0

क्या आपने [MyBatis जेनरेटर] (https://code.google.com/p/mybatis/wiki/Generator) का उपयोग करने पर देखा है? यह आपके लिए हाथ से कोडित एसक्यूएल की एक टन बचाए जाने के लिए मूल सीआरयूडी संचालन उत्पन्न करेगा, इसलिए आपको केवल जटिल जटिलताओं को लिखना होगा, आदि। आप अपने डीएओ में जेनरेट कोड का उपयोग कर सकते हैं और आपके द्वारा चुने गए चयन तर्क को बहुत से स्थानांतरित कर सकते हैं आपका एक्सएमएल डीएओ में। – clav

उत्तर

1

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

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

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

एक सुपर सरल दृष्टिकोण उपयोगकर्ताओं के हैशकोड को चुनने के बाद स्टोर करना होगा और जांचें कि isUserDirty() नामक विधि का उपयोग करके हैशकोड बदल गया है या नहीं। <if test="isUserDirty"> का उपयोग करके आप बस उस स्थिति को अपने मैपिंग के भीतर से जांच सकते हैं। यह निश्चित रूप से एक बहुत ही सामान्य दृष्टिकोण नहीं है और एक सभ्य हैशकोड() कार्यान्वयन पर निर्भर करता है। अधिक सामान्य दृष्टिकोण के लिए एक समान प्रश्न के लिए लियोब्लॉय के answer पर एक नज़र डालें। बेशक यह अभी भी थोड़ा सा सरल हो सकता है, खासकर जब से हम कई रिश्तेदारों से बात कर रहे हैं। कौन सा दृष्टिकोण सबसे अच्छा है आपके मामले पर निर्भर करता है।

अब आपको पता होना चाहिए कि क्या करना है। सौभाग्य!

डेल्टा के डालने और हटाने के बजाय पीएस मैं एक साधारण ओवरराइट की सलाह दूंगा: लेनदेन में सभी को सम्मिलित करें। आपकी अस्थायी तालिका रणनीति एक अनुकूलन रणनीति है जो वास्तव में आपके डेटाबेस के प्रदर्शन में सुधार नहीं कर सकती है, वास्तव में मेरा अनुमान यह होगा कि यह संभवतः इसे और भी खराब कर देगा। यदि आपने इस रणनीति को सही ढंग से प्रोफाइल किया है और पता है कि आप क्या कर रहे हैं तो आप इस पोस्टस्क्रिप्ट को अनदेखा कर सकते हैं।

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