2009-06-08 12 views
6

मैं many reasons के लिए तैयार बयान का उपयोग करना चाहता हूं।मुझे तैयार किए गए स्टेटमेंट बनाने के लिए कनेक्शन की आवश्यकता क्यों है?

/* This opens a connection, executes the query, and closes the connection */ 
public static void executeNonQuery(String queryString); 

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

क्या स्ट्रिंग.फॉर्मैट() का उपयोग किये बिना मुझे क्या करना है?

+0

आपकी executeNonQuery विधि में एक समस्या है: कनेक्शन प्राप्त करना। यदि आप इस विधि को निष्पादित करते समय हर बार एक बनाते हैं, तो आपके पास अधिक से अधिक निष्पादित करने में प्रदर्शन समस्याएं होती हैं (कनेक्शन बनाना और बंद करना महंगा है)। यदि यह किसी ऑब्जेक्ट पर encapsulated है जो केवल पहली कॉल पर कनेक्शन बनाता है, तो आपको एक समस्या होगी: इसे बंद करने के लिए कब? शायद समय पर आधारित? यदि आप कैश करने के लिए स्थिर फ़ील्ड का उपयोग करते हैं, तो सावधान रहें कि इसे एकत्र नहीं किया जाएगा। एक कनेक्शन को कैश करते समय, समवर्ती कॉल से सावधान रहें, हालांकि: लॉक मैकेनिज्म (जैसे सिंक्रोननाइज्ड) के बिना, आप बहुत सारे कनेक्शन बना सकते हैं। –

उत्तर

14

मुझे तैयार किए गए स्टेटमेंट बनाने के लिए कनेक्शन की आवश्यकता क्यों है?

क्योंकि RDBMS में प्रति-कनेक्शन आधार पर बयान तैयार किए गए हैं।

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

यह सब क्वेरी पार्सिंग के दौरान किया जाता है।

वहाँ String.format()

का उपयोग कर नहीं दिखाई दे रहा तुम क्यों String.format() यहाँ की जरूरत के बिना मैं क्या चाहते करने के लिए एक रास्ता है।

आप अपनी क्वेरी को कक्षा के रूप में कार्यान्वित कर सकते हैं, कनेक्शन बना सकते हैं और कक्षा कन्स्ट्रक्टर में क्वेरी तैयार कर सकते हैं और फिर इसे विधि में निष्पादित कर सकते हैं।

एक parametrized क्वेरी आम तौर पर इस तरह दिखता है:

SELECT * 
FROM table 
WHERE col1 = ? 
     AND col2 = ? 

, जहां बाध्य पैरामीटर क्वेरी निष्पादन के दौरान ? के लिए प्रतिस्थापित किया जा जाएगा।

आप एक static विधि चाहते हैं:

  • एक static कनेक्शन संभाल बनाएँ।
  • key के रूप में parametrized क्वेरी टेक्स्ट का उपयोग करके तैयार प्रश्नों की हैश तालिका बनाएं, और value के रूप में तैयार क्वेरी के लिए हैंडल बनाएं।
  • जब भी आप कोई क्वेरी निष्पादित करना चाहते हैं, तो इसके हैंडल को ढूंढें (या इसे प्राप्त करने पर इसे बनाएं) और पैरामीटर को बाध्य करने और क्वेरी निष्पादित करने के लिए उपयोग करें।
1

क्यों नहीं "एप्लिकेशन" तर्क आपके द्वारा बनाई गई डेटा परत का उपयोग करता है जो उस प्रकार की इंटरफ़ेस विधि पेश कर सकता है?

आपकी डेटा परत तब executeNonQuery विधि के भीतर कनेक्शन बनाने, बयानों की तैयारी आदि को संभालने में सक्षम हो सकती है।

मुझे लगता है कि यदि आप अपनी क्वेरी/स्टेटमेंट में पैरामीटर को स्ट्रिंग में मर्ज करने का प्रयास कर रहे हैं, तो आप अपने आप को पैर में शूटिंग कर रहे हैं और वास्तव में तैयार किए गए पैरामीटर की पैरामीटर कार्यक्षमता का उपयोग नहीं कर रहे हैं। निश्चित नहीं है कि आप ऐसा क्यों करना चाहते हैं।

आप स्प्रिंग जैसे एपीआई का उपयोग करना भी चाहेंगे, जिसमें JdbcTemplate कक्षाएं हैं जो आपके द्वारा कनेक्शन से जुड़े सभी कनेक्शन को सारणी कर सकती हैं, लेकिन फिर भी आपको Map में पैरामीटर के साथ काम करने की अनुमति मिलती है।

0

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

public void executeNoCommit(Connection conn, 
          String sql, 
          List params, 
          ResultSetProcessor processor) throws SQLException { 
    PreparedStatement stmt = null; 
    ResultSet rs = null; 
    int updateCount = 0; 
    Iterator it; 
    int paramIndex = 1; 
    boolean query; 

    try { 
     stmt = conn.prepareStatement(sql); 

     if (params != null) { 
      it = params.iterator(); 
      while (it.hasNext()) { 
       stmt.setObject(paramIndex, it.next()); 
       paramIndex++; 
      } 
     } 

     query = stmt.execute(); 
     if (query) { 
      rs = stmt.getResultSet(); 
     } 
     else { 
      updateCount = stmt.getUpdateCount(); 
     } 

     processor.process(rs, updateCount); 
    } 
    finally { 
     if (rs != null) { 
      try { 
       rs.close(); 
      } 
      catch (SQLException e) { 
       log.error(e); 
      } 
     } 

     if (stmt != null) { 
      try { 
       stmt.close(); 
      } 
      catch (SQLException e) { 
       log.error(e); 
      } 
     } 
    } 
} 
+0

क्या आप कोड पोस्ट कर सकते हैं? – ripper234

0

आप शायद अपाचे कॉमन्स पुस्तकालयों में DbUtils पैकेज की तरह कुछ हैं: [http://commons.apache.org/dbutils/index.html][1]

QueryRunner वर्ग आप मैन्युअल रूप से PreparedStatements बनाने के लिए, या यहाँ तक कि के लिए एक खुला संबंध नहीं है बिना एसक्यूएल स्टेटमेंट्स को निष्पादित करने देता है मामला। उदाहरण पृष्ठ से:

QueryRunner run = new QueryRunner(dataSource); 
try 
{ 
    // Create an object array to hold the values to insert 
    Object[] insertParams = {"John Doe", new Double(1.82)}; 
    // Execute the SQL update statement and return the number of 
    // inserts that were made 
    int inserts = run.update("INSERT INTO Person (name,height) VALUES (?,?)", 
           insertParams); 

    // Now it's time to rise to the occation... 
    Object[] updateParams = {new Double(2.05), "John Doe"}; 
    int updates = run.update("UPDATE Person SET height=? WHERE name=?", 
           updateParams); 
} 
catch(SQLException sqle) { 
    // Handle it 
} 

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