今天主要讲解下经常使用的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实现类来一块儿使用。 安全