2011-09-02 7 views
12

संभव डुप्लिकेट:
when to close Connection, Statement, PreparedStatement and ResultSet in JDBCअच्छा प्रथाओं: JDBC कनेक्शन

मैं एक JDBC कनेक्शन के लिए एक सरल आवरण लिखा है और यह काम करता है, लेकिन मैं सर्वोत्तम प्रथाओं के साथ यह सुधार करना चाहते हैं यथासंभव। इसमें मूल रूप से open(), close(), isOpened(), select(), insert(), update(), delete() और batch() जैसी विधियां हैं। सादगी के लिए मैं केवल पहले 4 तरीकों को पोस्ट करूंगा।

public class Query{ 
    private Connection con; 
    private PreparedStatement ps; 
    private ResultSet rs; 

    //Database.open() returns a Connection ready to use 
    public void open (Database database) throws DatabaseException, SQLException{ 
     if (!isOpened()){ 
      con = database.open(); 
     } 
    } 

    public void close() throws SQLException{ 
     if (isOpened()){ 
      if (ps != null) ps.close(); 
      con.close(); 
      con = null; 
     } 
    } 

    public boolean isOpened(){ 
     return con != null; 
    } 

    //The query string is the query without the word "select" and can use placeholders (?) 
    //The args param it's just an array owith the values of this placeholders 
    public ResultSet select (String query, Object[] args) throws SQLException{ 
     if (ps != null) ps.close(); 

     if (isOpened()){ 
      ps = con.prepareStatement ("select " + query); 
      if (args != null){ 
       for (int i=0; i<args.length; i++){ 
        ps.setObject (i+1, args[i]); 
       } 
      } 
      rs = ps.executeQuery(); 
     } 

     return rs; 
    } 
} 

नोट्स:

  • समान क्वेरी वस्तु उदाहरण खोलने और, यह बंद करने के लिए और फिर से खोलने के बाद, पुन: उपयोग किया जा सकता है।
  • मैं प्रत्येक क्वेरी के लिए कनेक्शन बंद करने नहीं कर रहा हूँ, मैं सिर्फ तैयार बयान बंद करने कर रहा हूँ (यह सही है या मैं तैयार बयान खोला क्योंकि कनेक्शन वस्तु यह बंद हो जाएगा छोड़ सकते हैं?)
  • जब मैं Connection बंद करें, सभी PreparedStatement एस और उनके ResultSet एस भी बंद हैं, है ना?

उपयोग:

Database database; 

//Database initialization 

Query query = new Query(); 


query.open (database); 

ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" }); 
doSomethingWithResult1 (rs); 

//Connection is not closed here 

ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 }); 
doSomethingWithResult2 (rs); 

query.close(); 


query.open (database); 

ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" }); 
doSomethingWithResult1 (rs); 

//Connection is not closed here 

ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 }); 
doSomethingWithResult2 (rs); 

query.close(); 

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

+7

प्रत्येक क्वेरी के लिए कनेक्शन बंद करना और पुनः खोलना एक बुरा विचार है। एक कनेक्शन बनाना वास्तव में महंगा है। – bdares

+1

तो क्या मैं तैयार किए गए स्टेटमेंट को खोला जा सकता हूं या क्या मुझे इसे प्रत्येक क्वेरी के लिए बंद करना चाहिए? –

+0

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

उत्तर

12

आपको इसके साथ किए जाने के बाद तैयार किए गए स्टेटमेंट को बंद करना होगा और इससे पहले कि आप एक ही कनेक्शन पर एक नया निर्माण करें। मुझे गंभीर समस्याएं आई हैं क्योंकि मैंने तैयार किए गए स्तर को बंद नहीं किया था। यह पता चला कि डेटाबेस सर्वर पर आवंटित संसाधन थे जिन्हें केवल PreparedStatement.close() के स्पष्ट कॉल के बाद ही मुक्त कर दिया गया था।

जैसा कि bdares ने टिप्पणी की थी, कनेक्शन को खोला जाना चाहिए और जितनी बार संभव हो सके बंद कर दिया जाना चाहिए।

1

सर्वोत्तम paectise है: सभी प्रश्नों के लिए एकल कनेक्शन ऑब्जेक्ट का उपयोग करें यदि उन queires एक ही विधि का हिस्सा हैं और प्रत्येक क्वेरी के लिए इसे तैयार किए जाने के बाद, तैयार किए गए स्टेटमेंट को बंद कर दें।

1

कनेक्शन कनेक्शन का उपयोग करें। तो आप बनाने के लिए नहीं बनाते हैं।

+0

जब मैं डेटाबेस प्रारंभ करता हूं तो कनेक्शन पूल बनाया जाता है। कनेक्शन जो मेरा डेटाबेस.ऑपेन() विधि रिटर्न पूल से कनेक्शन है क्योंकि मैं डेटास्रोत का उपयोग कर रहा हूं। –

5

कनेक्शन पूलिंग

एक कनेक्शन पूल का प्रयोग करें। आपके ऐप में प्रत्येक लेनदेन को इस पूल से कनेक्शन मिलेगा, आवश्यक सभी चीजें निष्पादित करें, रोलबैक करें या प्रतिबद्ध करें और कनेक्शन बंद करें (यह पूल में कॉन वापस कर देगा)।

आप क्वेरी ऑब्जेक्ट को पूल के संदर्भ में दे सकते हैं और खुले कनेक्शन को प्राप्त करेंगे और बंद हो जाएगा (वास्तव में इसे वापस कर देगा)।

तैयार वक्तव्य

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

कैसे?

  • पिछले पुनश्च खुला
  • बनाए रखें आप कनेक्शन या जो कुछ भी बंद करते हैं, यह
  • बंद यदि आप पिछले पुन: उपयोग के पी एस आप
  • बचाया अगर यह एक ही नहीं है की तुलना में एक ही क्वेरी स्ट्रिंग के लिए क्वेरी क्वेरी स्ट्रिंग ... इसे बंद करें और एक नया

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

  • कोई संबंधित समस्या नहीं^_^