今天主要講解下經常使用的Handler,Handler講完以後,就能對dbutils總體有了瞭解了。 java
/** * 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及實現類,會在下一篇裏講到。 數據庫
/** * <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
/** * <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實現相似。 編程
/** * <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; } }
/** * <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; } }
/** * <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實現類來一塊兒使用。 安全