2012-08-15 269 views
2

我使用Spring JDBC + Oracle 10g出現了一個奇怪的問題。這裏是我的DataSource配置:設置defaultRowPrefetch對查詢沒有影響

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 
     destroy-method="close"> 
     <property name="driverClassName" value="oracle.jdbc.OracleDriver" /> 
     <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" /> 
     <property name="username" value="admin" /> 
     <property name="password" value="admin" /> 
     <property name="validationQuery" value="SELECT 1 FROM DUAL"/> 
     <property name="testOnBorrow" value="true"/> 
     <property name="connectionProperties" value="defaultRowPrefetch=1000" /> 
    </bean> 

起初,我還以爲是被設定的ConnectionProperties中值,但正如我微調在SQL Developer中的查詢(成本從3670走到285和計劃講解從去:45至: 03),應用程序中的時間從原來的15秒起不會波動。刪除connectionProperties設置沒有效果。所以,我所做的就是這樣的:

DAO類

private List<Activity> getAllActivitiesJustJDBC() { 
    String query = "select * " + "from activity a, work_order w " 
      + "where a.ac_customer = 'CSC' " 
      + "and w.wo_customer = a.ac_customer " 
      + "and a.ac_workorder = w.wo_workorder "; 
    long startTime = System.currentTimeMillis(); 
    List<Activity> activities = new ArrayList<Activity>(); 
    try { 
     Connection conn = jdbcTemplate.getDataSource().getConnection(); 
     PreparedStatement st = conn.prepareStatement(query); 
     st.setFetchSize(1000); 
     ResultSet rs = st.executeQuery(); 
     ActivityMapper mapper = new ActivityMapper(); 
     while (rs.next()) { 
      Activity activity = mapper.mapRow(rs, 1); 
      activities.add(activity); 
     } 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    System.out.println("Time it took...." 
      + (System.currentTimeMillis() - startTime)); 
    System.out.println("Number of activities = " + activities.size()); 
    return activities; 
} 

這一次,花了獲取11,115行的時間,平均需2秒。關鍵語句是setFetchSize(1000)。所以....我喜歡選項#2,但是我需要關閉連接還是Spring處理這個對我?在選項#1中,我將使用jdbcTemplate來調用查詢方法,使用我的數據對象傳遞參數化查詢和BeanPropertyRowMapper實例,然後返回List。

回答

0

從查看與此類似的其他問題來看,確實需要關閉從結果集開始的連接,然後是語句,然後是使用finally進行的連接。我還記得(從Spring之前的日子),我需要將所有圍繞try/catch的東西封裝起來,然後在關閉連接時發生異常時不做任何事情。

僅供參考,我想知道在使用Spring定義數據源時是否有設置讀取大小的方法。

這裏的最後一個方法:

private List<Activity> getAllActivitiesJustJDBC() { 
    String query = "select * " + "from activity a, work_order w " 
      + "where a.ac_customer = 'CSC' " 
      + "and w.wo_customer = a.ac_customer " 
      + "and a.ac_workorder = w.wo_workorder "; 
    long startTime = System.currentTimeMillis(); 
    List<Activity> activities = new ArrayList<Activity>(); 
    Connection conn = null; 
    PreparedStatement st = null; 
    ResultSet rs = null; 
    try { 
     conn = jdbcTemplate.getDataSource().getConnection(); 
     st = conn.prepareStatement(query); 
     st.setFetchSize(1000); 
     rs = st.executeQuery(); 
     while (rs.next()) { 
      activities.add(ActivityMapper.mapRow(rs)); 
     } 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    finally { 
     try { 
      rs.close(); 
      st.close(); 
      conn.close(); 
     } 
     catch (Exception ex){ 
      //Not much we can do here 
     } 
    } 
    System.out.println("Time it took...." 
      + (System.currentTimeMillis() - startTime)); 
    System.out.println("Number of activities = " + activities.size()); 
    return activities; 
}