设置defaultRowPrefetch对查询没有影响

时间:2012-08-15 22:08:08

标签: spring jdbc oracle11g

使用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实例,然后返回List。

1 个答案:

答案 0 :(得分: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;
}