今天主要讲解下常用的Handler,Handler讲完之后,就能对dbutils整体有了了解了。
来看下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;
}
它就只有一个方法声明,很简单,就不讲什么。
![](http://static.oschina.net/uploads/space/2013/0926/102727_na5B_198574.jpg)
在这里我会讲解: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方法。
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实现类来一起使用。