04-dbutils源碼之 各類ResultSetHandler實現類

 

今天主要講解下經常使用的Handler,Handler講完以後,就能對dbutils總體有了瞭解了。 java

來看下ResultSetHandler接口

/**
 * Implementations of this interface convert ResultSets into other objects.
 * 此接口的實現類將結果集轉化爲其餘的對象
 * @param <T> the target type the input ResultSet will be converted to.
 */
public interface ResultSetHandler<T> {

    /**
     * Turn the <code>ResultSet</code> into an Object.
     * 將結果集轉換成對象
     * @param rs The <code>ResultSet</code> to handle.  It has not been touched
     * before being passed to this method.
     *
     * @return An Object initialized with <code>ResultSet</code> data. It is
     * legal for implementations to return <code>null</code> if the
     * <code>ResultSet</code> contained 0 rows.
     *
     * @throws SQLException if a database access error occurs
     */
    T handle(ResultSet rs) throws SQLException;

}

它就只有一個方法聲明,很簡單,就不講什麼。 sql

 

在這裏我會講解:BeanHandler、ArrayHandler、BeanListHandler、MapHandler、ScalarHandler這5個Handler。剩下的AbstractKeyedHandler以及實現類和AbstractListHandler及實現類,會在下一篇裏講到。 數據庫

BeanHandler源碼:

/**
 * <code>ResultSetHandler</code> implementation that converts the first
 * <code>ResultSet</code> row into a JavaBean. This class is thread safe.
 * ResultSetHandler實現類將結果集的第一行轉換成一個javabean
 * @param <T> the target bean type
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class BeanHandler<T> implements ResultSetHandler<T> {

    /**
     * The Class of beans produced by this handler.
     * 這個handler要返回的bean的Class
     */
    private final Class<T> type;

    /**
     * The RowProcessor implementation to use when converting rows
     * into beans.
     * 將行轉換成bean時,使用RowProcessor的哪一個實現類。默認使用的是BasicRowProcessor
     */
    private final RowProcessor convert;

    /**
     * Creates a new instance of BeanHandler.
     * 建立一個BeanHandler對象,默認使用的是BasicRowProcessor
     * @param type The Class that objects returned from <code>handle()</code>
     * are created from.
     */
    public BeanHandler(Class<T> type) {
    	//static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * Creates a new instance of BeanHandler.
     * 建立一個BeanHandler對象。能夠自定義RowProcessor
     * @param type The Class that objects returned from <code>handle()</code>
     * are created from.
     * @param convert The <code>RowProcessor</code> implementation
     * to use when converting rows into beans.
     */
    public BeanHandler(Class<T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    /**
     * Convert the first row of the <code>ResultSet</code> into a bean with the
     * <code>Class</code> given in the constructor.
     * 將RS中的第一行記錄轉換成一個bean對象,這個bean對象經過在構造器中給定的Class建立。使用了反射。
     * @param rs <code>ResultSet</code> to process.
     * @return An initialized JavaBean or <code>null</code> if there were no
     * rows in the <code>ResultSet</code>.
     *
     * @throws SQLException if a database access error occurs
     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
     */
    @Override
    public T handle(ResultSet rs) throws SQLException {
    	/*
    	 * 若是有RS中有記錄的時候才進行處理,不然返回null。屬性convert在構造函數中賦值了
    	 */
        return rs.next() ? this.convert.toBean(rs, this.type) : null;
    }

}

BeanHandler的實現簡單,就是調用了BasicRowProcessor中的toBean方法。 apache

 

BeanListHandler源碼:

/**
 * <code>ResultSetHandler</code> implementation that converts a
 * <code>ResultSet</code> into a <code>List</code> of beans. This class is
 * thread safe.
 * 此實現類將結果集轉換成bean的集合
 * @param <T> the target bean type
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class BeanListHandler<T> implements ResultSetHandler<List<T>> {

    /**
     * The Class of beans produced by this handler.
     */
    private final Class<T> type;

    /**
     * The RowProcessor implementation to use when converting rows
     * into beans.
     * 使用的仍是BasicRowProcessor
     */
    private final RowProcessor convert;

    /**
     * Creates a new instance of BeanListHandler.
     *
     * @param type The Class that objects returned from <code>handle()</code>
     * are created from.
     */
    public BeanListHandler(Class<T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * Creates a new instance of BeanListHandler.
     *
     * @param type The Class that objects returned from <code>handle()</code>
     * are created from.
     * @param convert The <code>RowProcessor</code> implementation
     * to use when converting rows into beans.
     */
    public BeanListHandler(Class<T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    /**
     * Convert the whole <code>ResultSet</code> into a List of beans with
     * the <code>Class</code> given in the constructor.
     * 調用了BasicRowProcessor的toBeanList方法。
     * @param rs The <code>ResultSet</code> to handle.
     *
     * @return A List of beans, never <code>null</code>.
     *
     * @throws SQLException if a database access error occurs
     * @see org.apache.commons.dbutils.RowProcessor#toBeanList(ResultSet, Class)
     */
    @Override
    public List<T> handle(ResultSet rs) throws SQLException {
        return this.convert.toBeanList(rs, type);
    }
}

BeanListHandler跟BeanHandler實現相似。 編程

ArrayHandler源碼:

/**
 * <code>ResultSetHandler</code> implementation that converts a
 * <code>ResultSet</code> into an <code>Object[]</code>. This class is
 * thread safe.
 * <p>
 * 將ResultSet中的一行記錄變成一個Object[]數組,此類是線程安全的
 * </p>
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class ArrayHandler implements ResultSetHandler<Object[]> {

    /**
     * Singleton processor instance that handlers share to save memory.  Notice
     * the default scoping to allow only classes in this package to use this
     * instance.
     */
    static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();

    /**
     * The RowProcessor implementation to use when converting rows
     * into arrays.
     */
    private final RowProcessor convert;

    /**
     * Creates a new instance of ArrayHandler using a
     * <code>BasicRowProcessor</code> for conversion.
     */
    public ArrayHandler() {
        this(ROW_PROCESSOR);
    }

    /**
     * Creates a new instance of ArrayHandler.
     *
     * @param convert The <code>RowProcessor</code> implementation
     * to use when converting rows into arrays.
     */
    public ArrayHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /**
     * Places the column values from the first row in an <code>Object[]</code>.
     * 將第一行的記錄編程Object[]
     * @param rs <code>ResultSet</code> to process.
     * @return An Object[] or <code>null</code> if there are no rows in the
     * <code>ResultSet</code>.
     *
     * @throws SQLException if a database access error occurs
     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
     */
    @Override
    public Object[] handle(ResultSet rs) throws SQLException {
    	//有記錄的話,就將第一行記錄變成一個Object[]
        return rs.next() ? this.convert.toArray(rs) : null;
    }

}

 

MapHandler源碼:

/**
 * <code>ResultSetHandler</code> implementation that converts the first
 * <code>ResultSet</code> row into a <code>Map</code>. This class is thread
 * safe.
 *
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class MapHandler implements ResultSetHandler<Map<String, Object>> {

    /**
     * The RowProcessor implementation to use when converting rows
     * into Maps.
     */
    private final RowProcessor convert;

    /**
     * Creates a new instance of MapHandler using a
     * <code>BasicRowProcessor</code> for conversion.
     */
    public MapHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * Creates a new instance of MapHandler.
     *
     * @param convert The <code>RowProcessor</code> implementation
     * to use when converting rows into Maps.
     */
    public MapHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /**
     * Converts the first row in the <code>ResultSet</code> into a
     * <code>Map</code>.
     * @param rs <code>ResultSet</code> to process.
     * @return A <code>Map</code> with the values from the first row or
     * <code>null</code> if there are no rows in the <code>ResultSet</code>.
     *
     * @throws SQLException if a database access error occurs
     *
     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
     */
    @Override
    public Map<String, Object> handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toMap(rs) : null;
    }

}

ScalarHandler源碼:

/**
 * <code>ResultSetHandler</code> implementation that converts one
 * <code>ResultSet</code> column into an Object. This class is thread safe.
 * 將結果集中第一行的第一列的值變成一個對象。便是單值的。
 * @param <T> The type of the scalar
 * @see org.apache.commons.dbutils.ResultSetHandler
 */
public class ScalarHandler<T> implements ResultSetHandler<T> {

    /**
     * The column number to retrieve.
     */
    private final int columnIndex;

    /**
     * The column name to retrieve.  Either columnName or columnIndex
     * will be used but never both.
     */
    private final String columnName;

    /**
     * Creates a new instance of ScalarHandler.  The first column will
     * be returned from <code>handle()</code>.
     * 默認會返回結果集中第一行的第一列的值
     */
    public ScalarHandler() {
        this(1, null);
    }

    /**
     * Creates a new instance of ScalarHandler.
     *
     * @param columnIndex The index of the column to retrieve from the
     * <code>ResultSet</code>.
     */
    public ScalarHandler(int columnIndex) {
        this(columnIndex, null);
    }

    /**
     * Creates a new instance of ScalarHandler.
     *
     * @param columnName The name of the column to retrieve from the
     * <code>ResultSet</code>.
     */
    public ScalarHandler(String columnName) {
        this(1, columnName);
    }

    /** Helper constructor
     * @param columnIndex The index of the column to retrieve from the
     * <code>ResultSet</code>.
     * @param columnName The name of the column to retrieve from the
     * <code>ResultSet</code>.
     */
    private ScalarHandler(int columnIndex, String columnName) {
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    /**
     * Returns one <code>ResultSet</code> column as an object via the
     * <code>ResultSet.getObject()</code> method that performs type
     * conversions.
     * @param rs <code>ResultSet</code> to process.
     * @return The column or <code>null</code> if there are no rows in
     * the <code>ResultSet</code>.
     *
     * @throws SQLException if a database access error occurs
     * @throws ClassCastException if the class datatype does not match the column type
     *
     * @see org.apache.commons.dbutils.ResultSetHandler#handle(java.sql.ResultSet)
     */
    // We assume that the user has picked the correct type to match the column
    // so getObject will return the appropriate type and the cast will succeed.
    @SuppressWarnings("unchecked")
    @Override
    public T handle(ResultSet rs) throws SQLException {

        if (rs.next()) {
        	//若是列名爲null,那麼就使用列碼
            if (this.columnName == null) {
                return (T) rs.getObject(this.columnIndex);
            } else {
                return (T) rs.getObject(this.columnName);
            }

        } else {
            return null;
        }
    }
}

 ScalarHandler用於獲取單值,經常使用的是計算表的記錄數count(*)。下面的代碼是測試代碼。用的數據庫仍是以前的。 數組

 

@Test
	public void testScalarHandler() throws Exception{
		String sql = "select * from t_user where id=?";
		Object[] params = new Object[]{3};
		ResultSetHandler<String> rsh = new ScalarHandler<String>(2);
		
		System.out.println(queryRunner.query(sql, rsh, params));
	}

 

這幾個就是經常使用的Handler了。平時開發的話,通常是夠用了。在查詢方面,使用了策略模式。用戶能夠自定義ResultSetHandler,用戶本身來實現對結果集的處理,也能夠結合自定義的RowProcessor實現類來一塊兒使用。 安全

相關文章
相關標籤/搜索