2010-08-17 19 views
7

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

public Connection getConnection() { 
    // Call to singleton handling JDBC stuff 
    return Database.getInstance().getCon(); 
} 

public boolean isConnectionAvailable(){  
    if(getConnection() != null){ 
     return true; 
    } 

    return false; 
} 

public PreparedStatement getPreparedStatement(String sqlStatement){ 
    Connection connection = getConnection(); 
    PreparedStatement pS = null; 

    if(connection != null){ 
     try { 
      pS = connection.prepareStatement(sqlStatement); 
     } catch (SQLException e) { 
      return null; 
     } 
    } 

    return pS; 
} 

संपादित करें: मैं इस प्रश्न reformulate सकता है के रूप में यह यहाँ क्या महत्वपूर्ण है DAOs लेखन के बारे में जानकारी शामिल करने के लिए।

+3

डेटाबेस कनेक्शन पहुंच –

+0

के लिए सिंगलेट का उपयोग न करें I अक्सर यह सुनते हैं। लेकिन जब आप सादे जावा के साथ काम कर रहे हों तो विकल्प क्या है? –

उत्तर

12

मैं इस कार्यान्वयन से सहमत नहीं हूं।

सबसे पहले, डीएओ को उन सेवाओं द्वारा उनकी कनेक्शन जानकारी दी जानी चाहिए जो काम और लेनदेन की इकाइयां हैं।

दूसरा, मुझे एक इंटरफ़ेस दिखाई नहीं देता है।

तीसरा, मुझे मॉडल या डोमेन ऑब्जेक्ट्स नहीं दिखते हैं।

चौथा, तैयार बयान केवल आंतरिक कार्यान्वयन का हिस्सा होना चाहिए। अगर वे आपके डीएओ से बाहर निकल रहे हैं, तो आप इसे गलत कर रहे हैं।

पांचवें, वस्तु से बाहर एक तैयार बयान पारित करने से इसे बंद करने और बहुत कम स्पष्ट सफाई की जिम्मेदारी मिलती है। आपका डीएओ किसी भी समय संसाधन रिसाव की मौत मर जाएगा।

यहां एक सामान्य डीएओ के लिए एक इंटरफेस है। आप देखेंगे कि यह सभी सीआरयूडी संचालन है, जिसमें कनेक्शन से कोई संदर्भ नहीं है या जावा से कोई इंटरफेस नहीं है।एसक्यूएल पैकेज:

package persistence; 

import java.io.Serializable; 
import java.util.List; 

public interface GenericDao<T, K extends Serializable> 
{ 
    T find(K id); 
    List<T> find(); 
    List<T> find(T example); 
    List<T> find(String queryName, String [] paramNames, Object [] bindValues); 

    K save(T instance); 
    void update(T instance); 
    void delete(T instance); 
} 

आप इसके साथ एक लंबा सफर तय कर सकते हैं। यह एक बेहतर अमूर्त है। T आपका व्यावसायिक ऑब्जेक्ट प्रकार है, और K प्राथमिक कुंजी है।

+2

वसंत में एक सभ्य डीएओ ढांचा है: http://static.springsource.org/spring/docs/2.5.x/reference/dao.html – Dave

+0

सभ्य से अधिक। यह पालन करने के लिए मॉडल है। – duffymo

+0

उत्तर duffymo के लिए धन्यवाद। मुझे यह मानना ​​है कि मैं थोड़ा संघर्ष कर रहा हूं क्योंकि मुझे स्प्रिंग जैसे ढांचे का उपयोग न करने के लिए कहा गया है। यदि आपके पास एक उदाहरण है जिसे टेम्पलेट के रूप में उपयोग किया जा सकता है, तो यह स्वागत से अधिक होगा :)। –

3

getCon() एक नया Connection हर बार यह कहा जाता है देता है, या एक ThreadLocal कनेक्शन देता है, तो आप सुरक्षित हैं और synchronized

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

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

+0

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

3

जेडीबीसी कनेक्शन वर्ग को थ्रेड सुरक्षित होने की गारंटी नहीं है। यदि आपका डेटाबेस .getInstance()। GetCon() विधि हमेशा एक ही कनेक्शन को वापस कर रही है, तो आप समस्याओं में भाग लेंगे। यदि, हालांकि, यह एक पूल का उपयोग कर रहा है जैसे कि प्रत्येक कॉल प्राप्त करने के लिए कॉल()। GetCon() एक अलग कनेक्शन देता है जो आप ठीक होंगे।

यह कहा गया है कि, यदि आप प्रत्येक कॉल के साथ एक अलग कनेक्शन लौट रहे हैं तो कॉन() प्राप्त करें, तो getPreparedStatement() काम नहीं करेगा यदि आप दो तैयार स्टेटमेंट कॉल को उसी कनेक्शन (और उसी लेनदेन) का उपयोग करने के लिए चाहते हैं।

मुझे अपने डीएओ कक्षाओं के आधार के रूप में वसंत की जेडीबीसीटीप्लेट कक्षा पसंद है।

+0

'कनेक्शन' सिर्फ एक इंटरफ़ेस है, चाहे कार्यान्वयन थ्रेड-सुरक्षित हैं, जेडीबीसी ड्राइवर का उपयोग –

+0

अच्छा बिंदु पर नहीं किया जा रहा है। मैंने इसे स्पष्ट करने के लिए अपना उत्तर अपडेट किया। – Dave

0

मुझे ठीक लग रहा है। फ़ंक्शन सुरक्षित हैं।

2

आपको प्रत्येक धागे में एक ही कनेक्शन का उपयोग नहीं करना चाहिए। जेडीबीसी ड्राइवरों को थ्रेड सुरक्षित नहीं माना जाता है। यदि आप थ्रेड सुरक्षित कोड चाहते हैं, तो आपको प्रत्येक थ्रेड के लिए एक कनेक्शन बनाना चाहिए।

आपका शेष कोड सुरक्षित लगता है।

+0

क्या आपको लगता है कि मुझे डीएओ के अंदर किसी प्रकार का थ्रेडिंग मैकेनिज्म जोड़ना चाहिए? –

+0

यह आपका डीएओ नहीं है जो थ्रेड सुरक्षित नहीं है, यह कनेक्शन हिस्सा है। @ बोझो ने कहा कि अगर कॉन() प्रत्येक थ्रेड के लिए प्रत्येक बार एक विशिष्ट कनेक्शन लौटाता है तो कोई रेस स्थिति नहीं होती है। –

+0

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

2

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

निश्चित रूप से डीएओ डेटाबेस कनेक्शन प्राप्त करने का प्रभारी नहीं होना चाहिए, क्योंकि आप एक ही लेनदेन में एकाधिक डीएओ कॉल समूहित करना चाहते हैं। जिस तरह से स्प्रिंग करता है, वहां एक सेवा परत होती है जो एक लेन-देन के तरीकों को एक इंटरसेप्टर में लपेटती है जो डेटासोर्स से कनेक्शन खींचती है और इसे थ्रेडलोकल वैरिएबल में रखती है जहां डीएओ इसे पा सकते हैं।

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

+0

-1 "किसी को भी कच्चे जेडीबीसी का उपयोग नहीं करना चाहिए"। – GreenieMeanie

+0

-1 थोड़ा कठोर लगता है। क्या आपने कभी वसंत jdbc का उपयोग किया है? यह लगभग कच्चे जेडीबीसी है, जहां आप अभी भी पीएस और आरएस (यदि आप चाहें) में हेरफेर करेंगे लेकिन सभी अपवाद हैंडलिंग (और संसाधन प्रबंधन) और टीएक्स की देखभाल के साथ बातचीत के साथ। तो आपके पास रिसाव के कम जोखिम वाले डेटा तक कच्ची पहुंच का लाभ है। – Thierry

+0

मुझे लगता है कि यह एक बचाव योग्य स्थिति है, GreenieMeanie।मैं चाहूंगा कि लोग एसओ पर देखे गए जघन्य जेडीबीसी कोड के बजाय सिर्फ जेडीबीसी के लिए स्प्रिंग का उपयोग करें। मैंने नाथन ह्यूजेस को वोट दिया। – duffymo

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