2

Spring JDBC + Oracle 10g を使用すると奇妙な問題が発生します。これが私のdataSource構成です:

    <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 インスタンスを渡し、リストを返します。

4

1 に答える 1

0

これと同様の他の質問を見てわかりましたが、結果セット、ステートメント、最後に接続を閉じる必要があります。また、(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;
}
于 2012-08-16T13:54:10.483 に答える