2010-06-07 7 views
19

के साथ तैयार बयानों का उपयोग करके मैं जेडीबीसी टेम्पलेट का उपयोग कर रहा हूं और तैयार बयान का उपयोग कर डेटाबेस से पढ़ना चाहता हूं। मैं एक .csv फ़ाइल में कई लाइनों पर पुन: प्रयास करता हूं, और प्रत्येक पंक्ति पर मैं संबंधित मानों के साथ कुछ SQL चयन क्वेरी निष्पादित करता हूं।JDBCTemplate

मैं डेटाबेस से अपनी पढ़ाई तेज करना चाहता हूं लेकिन मुझे नहीं पता कि जेडीबीसी टेम्पलेट तैयार कथन के साथ काम करने के लिए कैसे प्राप्त करें।

PreparedStatementCreator और PreparedStatementSetter है। this example में से दोनों अज्ञात आंतरिक कक्षाओं के साथ बनाए जाते हैं। लेकिन तैयार किए गए स्टेटमेंट स्टर क्लास के अंदर मुझे उन मूल्यों तक पहुंच नहीं है जिन्हें मैं तैयार कथन में सेट करना चाहता हूं।

चूंकि मैं एक .csv फ़ाइल के माध्यम से पुनरावृत्ति कर रहा हूं, इसलिए मैं उन्हें स्ट्रिंग के रूप में हार्ड कोड नहीं कर सकता क्योंकि मैं उन्हें नहीं जानता। मैं उन्हें प्रीपेयरस्टेटमेंटसेटर में भी पास नहीं कर सकता क्योंकि कन्स्ट्रक्टर के लिए कोई तर्क नहीं है। और मेरे मूल्यों को फाइनल में सेट करना भी गूंगा होगा।

मैं तैयार कथन के निर्माण के लिए काफी सरल था। इस Java tutorial में के रूप में की तरह

PreparedStatement updateSales = con.prepareStatement(
    "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
updateSales.setInt(1, 75); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate(): 

कुछ।

उत्तर

2

मैंने अब PreparedStatement के साथ एक चयन कथन का प्रयास किया है, लेकिन यह पता चला कि यह जेडीबीसी टेम्पलेट से तेज़ नहीं था। शायद, जैसा कि मेज़मो ने सुझाव दिया है, यह स्वचालित रूप से तैयार बयान तैयार करता है।

वैसे भी, मेरे एसक्यूएल SELECT के कारण का कारण इतना धीमा था। WHERE खंड में मैंने हमेशा ऑपरेटर LIKE का उपयोग किया, जब मैं बस इतना करना चाहता था कि सटीक मिलान मिल रहा था। जैसा कि मैंने पाया है LIKE एक पैटर्न की खोज करता है और इसलिए यह बहुत धीमा है।

मैं अब ऑपरेटर = ऑपरेटर का उपयोग कर रहा हूं और यह बहुत तेज है।

9

निम्नलिखित का प्रयास करें:

PreparedStatementCreator creator = new PreparedStatementCreator() { 
    @Override 
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException { 
     PreparedStatement updateSales = con.prepareStatement(
     "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
     updateSales.setInt(1, 75); 
     updateSales.setString(2, "Colombian"); 
     return updateSales; 
    } 
}; 
+0

यह काम करेगा, लेकिन जो मूल्य मैं सेट करना चाहता हूं वह आंतरिक अज्ञात वर्ग के बाहर हैं। कक्षा के अंदर 'updateSales.setString (2, fileRow.getName()) जैसे कुछ होना चाहिए, लेकिन मैं कक्षा के अंदर' fileRow' फ़ॉर्म तक नहीं पहुंच सकता। –

+6

var fileRow को अंतिम – Inv3r53

3

मैं तैयार बयान में कम से कम एक पद्धति के लिए से निपटने को अलग चाहते हैं। इस मामले में, क्योंकि वहाँ कोई परिणाम नहीं हैं यह काफी सरल (और यह सोचते हैं कि कनेक्शन एक उदाहरण चर कि परिवर्तन नहीं करता है):

private PreparedStatement updateSales; 
public void updateSales(int sales, String cof_name) throws SQLException { 
    if (updateSales == null) { 
     updateSales = con.prepareStatement(
      "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?"); 
    } 
    updateSales.setInt(1, sales); 
    updateSales.setString(2, cof_name); 
    updateSales.executeUpdate(); 
} 

उस बिंदु पर, यह तो बुला का मामला है:

updateSales(75, "Colombian"); 

जो अन्य चीजों के साथ एकीकृत करने के लिए बहुत आसान है, हाँ? और यदि आप कई बार विधि को कॉल करते हैं, तो अपडेट केवल एक बार बनाया जाएगा और इससे चीजें बहुत तेज हो जाएंगी। खैर, यह मानते हुए कि आप पागल चीजें नहीं करते हैं जैसे प्रत्येक अपडेट अपने लेनदेन में करते हैं ...

ध्यान दें कि प्रकार निश्चित हैं। ऐसा इसलिए है क्योंकि किसी भी विशेष क्वेरी/अद्यतन के लिए, को ठीक किया जाना चाहिए ताकि डेटाबेस को अपनी नौकरी कुशलतापूर्वक करने की अनुमति दी जा सके। यदि आप बस एक CSV फ़ाइल से मनमाने ढंग से तार खींच रहे हैं, तो उन्हें तारों के रूप में पास करें। कोई लॉकिंग भी नहीं है; इसके बजाय एक ही थ्रेड से अलग-अलग कनेक्शनों को इस्तेमाल करने के लिए कहीं बेहतर है।

+0

के रूप में चिह्नित करें जो एक एकल मान लौटाते हैं, इस तकनीक का उपयोग करना भी बहुत आसान है। मुख्य जटिलता तब आती है जब आपके पास ऐसे प्रश्न होते हैं जो कई मान लौटाते हैं; या तो 'ResultSet' वापस करें या फिर कॉलबैक में पास करें जो प्रत्येक लौटाई पंक्ति को नियंत्रित करेगा (पाठ्यक्रम के' परिणामसेट 'से बाहर किए गए मानों के साथ)। –

+1

क्षमा करें, लेकिन मुझे नहीं पता कि मेरे जेडीबीसी टेम्पलेट समस्या के साथ क्या करना है। मैं एक तैयार स्थिति के साथ एक जेडीबीसी टेम्पलेट क्वेरी नहीं खिला सकता। ऐसा लगता है कि मुझे 'प्रीपेडस्टेटमेंट क्रिएटर' या 'प्रीपेडस्टेटमेंटसेटर' की आवश्यकता है। –

24

डिफ़ॉल्ट रूप से, JDBCTemplate अपने PreparedStatement आंतरिक रूप से करता है, यदि आप केवल .update(String sql, Object ... args) फ़ॉर्म का उपयोग करते हैं। वसंत, और आपका डेटाबेस, आपके लिए संकलित क्वेरी का प्रबंधन करेगा, इसलिए आपको स्प्रिंग की बचत करने वाली ग्रेस में से एक खोलने, बंद करने, संसाधन संरक्षण इत्यादि के बारे में चिंता करने की ज़रूरत नहीं है। A link to Spring 2.5's documentation on this. उम्मीद है कि यह चीजों को स्पष्ट बनाता है। साथ ही, at least some of Oracle's JDBC drivers. के मामले में, जेडीबीसी स्तर पर कथन कैशिंग किया जा सकता है, जो मैं सक्षम रूप से तुलना में बहुत अधिक विस्तार में जाऊंगा।

+3

लेकिन मैं डेटाबेस पर एक चयन करना चाहता हूं, अद्यतन नहीं। वसंत संदर्भ में http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/JdbcTemplate.html लिखा गया है, कि 'अपडेट' के साथ केवल एक डालने, अपडेट या हटाएं किया जासकताहे। –

+0

@ user3211068 वहाँ एक 'क्वेरी' विधि है जिसे आप चुन सकते हैं – linqu

+1

@mezmo क्या आप अपने कथन के लिए स्रोत जोड़ना चाहते हैं? और क्वेरी के लिए भी यही सच है (स्ट्रिंग एसक्यूएल, ...)? – leo

14
class Main { 
    public static void main(String args[]) throws Exception { 
     ApplicationContext ac = new 
      ClassPathXmlApplicationContext("context.xml", Main.class); 
     DataSource dataSource = (DataSource) ac.getBean("dataSource"); 
// DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource"); 

     JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 

     String prasobhName = 
     jdbcTemplate.query(
      "select first_name from customer where last_name like ?", 
      new PreparedStatementSetter() { 
       public void setValues(PreparedStatement preparedStatement) throws 
       SQLException { 
        preparedStatement.setString(1, "nair%"); 
       } 
      }, 
      new ResultSetExtractor<Long>() { 
       public Long extractData(ResultSet resultSet) throws SQLException, 
       DataAccessException { 
        if (resultSet.next()) { 
         return resultSet.getLong(1); 
        } 
        return null; 
       } 
      } 
     ); 
     System.out.println(machaceksName); 
    } 
} 
+0

क्वेरी भाग जावा 8 लैम्ब्डा शैली के रूप में: 'jdbcTemplate.query (वर्ग, ps -> ps.setString (1," मान "), (आरएस, i) -> rs.getLong (1)' –

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