Open Source Repository

Home /spring/spring-jdbc-3.0.5 | Repository Home



org/springframework/jdbc/core/RowCountCallbackHandler.java
/*
 * Copyright 2002-2006 the original author or authors.
 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 
 *      http://www.apache.org/licenses/LICENSE-2.0
 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.jdbc.core;

import org.springframework.jdbc.support.JdbcUtils;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

/**
 * Implementation of RowCallbackHandler. Convenient superclass for callback handlers.
 * An instance can only be used once.
 *
 <p>We can either use this on its own (for example, in a test case, to ensure
 * that our result sets have valid dimensions), or use it as a superclass
 * for callback handlers that actually do something, and will benefit
 * from the dimension information it provides.
 *
 <p>A usage example with JdbcTemplate:
 *
 <pre class="code">JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);  // reusable object
 
 * RowCountCallbackHandler countCallback = new RowCountCallbackHandler();  // not reusable
 * jdbcTemplate.query("select * from user", countCallback);
 * int rowCount = countCallback.getRowCount();</pre>
 *
 @author Rod Johnson
 @since May 3, 2001
 */
public class RowCountCallbackHandler implements RowCallbackHandler {

  /** Rows we've seen so far */
  private int rowCount;

  /** Columns we've seen so far */
  private int columnCount;

  /**
   * Indexed from 0. Type (as in java.sql.Types) for the columns
   * as returned by ResultSetMetaData object.
   */
  private int[] columnTypes;
  
  /**
   * Indexed from 0. Column name as returned by ResultSetMetaData object.
   */
  private String[] columnNames;


  /**
   * Implementation of ResultSetCallbackHandler.
   * Work out column size if this is the first row, otherwise just count rows.
   <p>Subclasses can perform custom extraction or processing
   * by overriding the <code>processRow(ResultSet, int)</code> method.
   @see #processRow(java.sql.ResultSet, int)
   */
  public final void processRow(ResultSet rsthrows SQLException {
    if (this.rowCount == 0) {
      ResultSetMetaData rsmd = rs.getMetaData();
      this.columnCount = rsmd.getColumnCount();
      this.columnTypes = new int[this.columnCount];
      this.columnNames = new String[this.columnCount];
      for (int i = 0; i < this.columnCount; i++) {
        this.columnTypes[i= rsmd.getColumnType(i + 1);
        this.columnNames[i= JdbcUtils.lookupColumnName(rsmd, i + 1);
      }
      // could also get column names
    }
    processRow(rs, this.rowCount++);
  }

  /** 
   * Subclasses may override this to perform custom extraction
   * or processing. This class's implementation does nothing.
   @param rs ResultSet to extract data from. This method is
   * invoked for each row
   @param rowNum number of the current row (starting from 0)
   */
  protected void processRow(ResultSet rs, int rowNumthrows SQLException {
  }


  /**
   * Return the types of the columns as java.sql.Types constants
   * Valid after processRow is invoked the first time.
   @return the types of the columns as java.sql.Types constants.
   <b>Indexed from 0 to n-1.</b>
   */
  public final int[] getColumnTypes() {
    return columnTypes;
  }
  
  /** 
   * Return the names of the columns.
   * Valid after processRow is invoked the first time.
   @return the names of the columns.
   <b>Indexed from 0 to n-1.</b>
   */
  public final String[] getColumnNames() {
    return columnNames;
  }

  /** 
   * Return the row count of this ResultSet
   * Only valid after processing is complete
   @return the number of rows in this ResultSet
   */
  public final int getRowCount() {
    return rowCount;
  }

  /** 
   * Return the number of columns in this result set.
   * Valid once we've seen the first row,
   * so subclasses can use it during processing
   @return the number of columns in this result set
   */
  public final int getColumnCount() {
    return columnCount;
  }

}