DBUtils学习----ResultSetHandler接口与实现

173 篇文章 16 订阅
23 篇文章 0 订阅

DBUtils用的最多的莫过于其结果集的处理,毕竟仅仅得到一个ResultSet屁用没有。而结果集的处理正是依赖于ResultSetHandler 接口及其实现类。
以下内容,我们着重分析该接口及其实现类的源码并给出使用方法。


ResultSetHandler 接口

package org.apache.commons.dbutils;

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

/**
 * 此接口的实现将 ResultSet 转换为其他对象
 * T: 目标类型(类型参数),也就是 ResultSet 转换为的对象的类型
 */
public interface ResultSetHandler<T> {

    /**
     * 方法说明:将 ResultSet 转换为一个对象
     *
     * rs: 要转换的 ResultSet
     * T: 返回用 ResultSet 数据初始化的对象
     * 如果 ResultSet 包含0行,那么实现返回 null 也是合法的
     * 数据库访问出错将会抛出 SQLException 异常
     */
    T handle(ResultSet rs) throws SQLException;

}

ResultSetHandler接口就是将ResultSet结果集映射为Bean、List、Map等Java中的对象或者集合。

ResultSetHandler 的实现
- 处理单行数据的类:ScalarHandler、ArrayHandler、MapHandler、BeanHandler
- 处理多行数据的类:BeanListHandler、AbstractListHandler(ArrayListHandler、MapListHandler、ColumnListHandler)、
AbstractKeyedHandler(KeyedHandler BeanMapHandler)
- 可扩展的类:BaseResultSetHandler


ScalarHandler

将结果集第一行的某一列放到某个对象中

package org.apache.commons.dbutils.handlers;

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

import org.apache.commons.dbutils.ResultSetHandler;

/**
 * ResultSetHandler 的实现
 * 将一个 ResultSet 列转换为对象
 * 这个类是线程安全的
 *
 * T: 要转化为的对象的类型
 */
public class ScalarHandler<T> implements ResultSetHandler<T> {

    /**
     * 检索的列编号(从1开始)
     */
    private final int columnIndex;

    /**
     * 检索的列名
     * columnName 与 columnIndex
     * 只会有一个被用到
     */
    private final String columnName;

    /**
     * 创建 ScalarHandler 的新实例
     * 第一列将会从 handle() 方法中返回
     */
    public ScalarHandler() {
        this(1, null);
    }

    /**
     * 创建 ScalarHandler 的新实例
     *
     * columnIndex: 检索的列编号
     */
    public ScalarHandler(int columnIndex) {
        this(columnIndex, null);
    }

    /**
     * 创建 ScalarHandler 的新实例
     *
     * columnName: 检索的列名
     */
    public ScalarHandler(String columnName) {
        this(1, columnName);
    }

    /** 辅助构造函数
     * columnIndex: 检索的列编号
     * columnName: 检索的列名
     */
    private ScalarHandler(int columnIndex, String columnName) {
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    /**
     * 通过 ResultSet.getObject() 方法返回一个 ResultSet 列作为一个对象,该方法执行类型转换
     * rs: ResultSet
     * 返回值: ResultSet 列, 如果 ResultSet 为空,则返回null
     *
     * 数据库访问出错抛出 SQLException 异常
     * 类数据类型(T)与列类型不匹配抛出 ClassCastException 异常
     */
    // 我们假设用户选择了正确的类型来匹配列
    // 因此 getObject() 将返回适当的类型,而类型转换将成功。
    @SuppressWarnings("unchecked")
    @Override
    public T handle(ResultSet rs) throws SQLException {
        if (rs.next()) {
            if (this.columnName == null) {
                return (T) rs.getObject(this.columnIndex);
            }
            return (T) rs.getObject(this.columnName);
        }
        return null;
    }
}

使用:

@Test
    public void testScalarHandler() {
        Connection connection = null;
        String sql = "SELECT COUNT(*) FROM persons";
        try {
            connection = JDBCTools.getConnection();
            Long rows = queryRunner.query(connection, sql, new ScalarHandler<Long>());
            System.out.println(rows);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

ArrayHandler

把结果集中的第一行数据转成对象数组

package org.apache.commons.dbutils.handlers;

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

import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 的一条记录转换为 Object[] 类型的数组
 * 这个类是线程安全的
 */
public class ArrayHandler implements ResultSetHandler<Object[]> {

    /**
     * BasicRowProcessor 单例
     * 只能够在该包下访问
     */
    static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();

    /**
     * 当 ResultSet 不存在记录时返回空的Object数组。
     */
    private static final Object[] EMPTY_ARRAY = new Object[0];

    /**
     * RowProcessor 实现
     */
    private final RowProcessor convert;

    /**
     * 使用 BasicRowProcessor 创建一个 ArrayHandler 实例
     */
    public ArrayHandler() {
        this(ROW_PROCESSOR);
    }

    /**
     * 创建一个 ArrayHandler 实例
     * convert: RowProcessor接口的实现类
     */
    public ArrayHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /**
     * 将 ResultSet 的首行记录转化为 Object[]
     */
    @Override
    public Object[] handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toArray(rs) : EMPTY_ARRAY;
    }

}

使用:

@Test
    public void testArrayHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons WHERE id = ?";
        try {
            connection = JDBCTools.getConnection();
            Object[] obj = queryRunner.query(connection, sql, new ArrayHandler(), 26);
            System.out.println(Arrays.toString(obj));
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

MapHandler

将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 的一条记录转换为一个 Map<String, Object>,Key对应列的别名,Value对应列的值
 * 该类是线程安全的
 */
public class MapHandler implements ResultSetHandler<Map<String, Object>> {

    /**
     * MapHandler 内部使用 RowProcessor 完成转换操作
     */
    private final RowProcessor convert;

    /**
     * 使用 BasicRowProcessor 创建一个 MapHandler 实例
     * ArrayHandler类中:static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();
     */
    public MapHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 创建一个 MapHandler 实例
     * convert:将记录转换为Map的 RowProcessor 的实现
     */
    public MapHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /**
     * 将 ResultSet 的一条记录转换为一个 Map<String, Object>
     */
    @Override
    public Map<String, Object> handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toMap(rs) : null;
    }

}

使用:

@Test
    public void testMapHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons WHERE id = ?";
        try {
            connection = JDBCTools.getConnection();
            Map<String, Object> map = queryRunner.query(connection, sql, new MapHandler(), 26);
            System.out.println(map.get("name"));
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

BeanHandler

将结果集中的第一行数据封装到一个对应的JavaBean实例中

package org.apache.commons.dbutils.handlers;

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

import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 的第一行转换为一个 JavaBean
 * 这个类是线程安全的
 */
public class BeanHandler<T> implements ResultSetHandler<T> {

    /**
     * 由 BeanHandler 生成的 JavaBean 的 Class 类型
     */
    private final Class<T> type;

    /**
     * RowProcessor 实现类,将 ResultSet 的记录转换为 JavaBean
     */
    private final RowProcessor convert;

    /**
     * 创建一个新的 BeanHandler 实例
     *
     * type:从 handle() 方法返回的对象的 Class 类型
     */
    public BeanHandler(Class<T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 创建一个新的 BeanHandler 实例
     */
    public BeanHandler(Class<T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    /**
     * 将 ResultSet 的第一行转换为一个 JavaBean
     */
    @Override
    public T handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toBean(rs, this.type) : null;
    }

}

使用:

    @Test
    public void testBeanHandler() {
        Connection connection = null;
        try {
            connection = JDBCTools.getConnection();
            String sql = "SELECT * FROM persons WHERE id = ?";
            Person person = queryRunner.query(connection, sql, new BeanHandler<>(Person.class), 26);
            System.out.println(person);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

以上四个实现类(ScalarHandler、ArrayHandler、MapHandler、BeanHandler)的共同特点:都是将ResultSet 结果集里的单行数据装换为相应的对象(T、Object[]、

AbstractListHandler 抽象类

实现自 ResultSetHandler 的抽象类,为了简化 ResultSet 转换为 List 的开发

该抽象类的继承类:
AbstractListHandler

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.dbutils.ResultSetHandler;

/**
 * 实现自 ResultSetHandler 的抽象类,为了简化 ResultSet 转换为 List 的开发
 */
public abstract class AbstractListHandler<T> implements ResultSetHandler<List<T>> {
    /**
     * 整个结果集处理器。它生成 List<T> 作为结果
     * 为了将单个行转换为Java对象,它使用handleRow(ResultSet)方法
     */
    @Override
    public List<T> handle(ResultSet rs) throws SQLException {
        List<T> rows = new ArrayList<T>();
        while (rs.next()) {
            rows.add(this.handleRow(rs));
        }
        return rows;
    }

    /**
     * 行处理器:将当前行转换为Java对象
     */
    protected abstract T handleRow(ResultSet rs) throws SQLException;
}

ArrayListHandler

把结果集中的每一行数据都转成一个对象数组,再存放到List中

package org.apache.commons.dbutils.handlers;

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

import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 转换为 List<Object[]>
 * 这个类是线程安全的
 */
public class ArrayListHandler extends AbstractListHandler<Object[]> {

    /**
     * RowProcessor 实现类, 将 ResultSet 的一条记录转换为 Object[] 数组
     */
    private final RowProcessor convert;

    /**
     * 创建一个新的 ArrayListHandler 实例
     * 使用 BasicRowProcessor 作为转换器
     */
    public ArrayListHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 创建一个新的 ArrayListHandler 实例
     */
    public ArrayListHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }


    /**
     * 将 ResultSet 的一条记录转换为 Object[] 数组
     */
    @Override
    protected Object[] handleRow(ResultSet rs) throws SQLException {
        return this.convert.toArray(rs);
    }

}

使用:

@Test
    public void testArrayListHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons";
        try {
            connection = JDBCTools.getConnection();
            List<Object[]> list = queryRunner.query(connection, sql, new ArrayListHandler());
            list.forEach(objects -> System.out.println(Arrays.toString(objects)));
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

MapListHandler

将结果集中的每一行数据都封装到一个Map里,然后再存放到List

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 转换为 List<Map<String, Object>>
 * 这个类是线程安全的
 */
public class MapListHandler extends AbstractListHandler<Map<String, Object>> {

    /**
     * RowProcessor 实现类,将 ResultSet 的一条记录转换为 Map<String, Object>
     */
    private final RowProcessor convert;

    /**
     * 创建一个新的 MapListHandler 实例
     * 使用 BasicRowProcessor 作为转换器
     */
    public MapListHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 创建一个新的 ArrayListHandler 实例
     * 可以自定义 RowProcessor 实现类
     */
    public MapListHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /**
     * 将 ResultSet 中的一行数据转换为 Map<String, Object>
     */
    @Override
    protected Map<String, Object> handleRow(ResultSet rs) throws SQLException {
        return this.convert.toMap(rs);
    }

}

使用:

@Test
    public void testMapListHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons";
        try {
            connection = JDBCTools.getConnection();
            List<Map<String, Object>> list = queryRunner.query(connection, sql, new MapListHandler());
            System.out.println(list);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

ColumnListHandler

将结果集中某一列的数据存放到List中

package org.apache.commons.dbutils.handlers;

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

/**
 * ResultSetHandler 的实现
 * that converts one
 * 将一个 ResultSet 列转换为对象列表
 * 这个类是线程安全的
 * T: 列的类型
 */
public class ColumnListHandler<T> extends AbstractListHandler<T> {

    /**
     * 检索的列编号(从1开始)
     */
    private final int columnIndex;

    /**
     * 检索的列名
     * columnName 与 columnIndex 只会有一个被用到
     */
    private final String columnName;

    /**
     * 创建一个新的 ColumnListHandler 实例
     * 每一行的第一列将从 handle() 方法中返回
     */
    public ColumnListHandler() {
        this(1, null);
    }

    /**
     * 创建一个新的 ColumnListHandler 实例
     * columnIndex:从 ResultSet 中检索的列的索引
     */
    public ColumnListHandler(int columnIndex) {
        this(columnIndex, null);
    }

    /**
     * 创建一个新的 ColumnListHandler 实例
     * columnName:从 ResultSet 中检索的列的名称
     */
    public ColumnListHandler(String columnName) {
        this(1, columnName);
    }

    /** 私有构造函数
     * columnIndex:从 ResultSet 中检索的列的索引
     * columnName:从 ResultSet 中检索的列的名称
     */
    private ColumnListHandler(int columnIndex, String columnName) {
        super();
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    /**
     * 返回一个 ResultSet 列值作为对象
     */
    // 我们假设用户选择了正确的类型来匹配列
    // 因此 getObject 将返回适当的类型,而类型转换将成功
    @SuppressWarnings("unchecked")
    @Override
    protected T handleRow(ResultSet rs) throws SQLException {
        if (this.columnName == null) {
            return (T) rs.getObject(this.columnIndex);
        }
        return (T) rs.getObject(this.columnName);
   }

}

使用:

@Test
    public void testColumnListHandler() {
        Connection connection = null;
        String sql = "SELECT name FROM persons";
        try {
            connection = JDBCTools.getConnection();
            List<String> list = queryRunner.query(connection, sql, new ColumnListHandler<String>());
            list.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

BeanListHandler

将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现
 * 将 ResultSet 转换为一个 List<JavaBean>
 * 这个类是线程安全的
 */
public class BeanListHandler<T> implements ResultSetHandler<List<T>> {

    /**
     * 由 BeanListHandler 生成的 JavaBean 的 Class 类型
     */
    private final Class<T> type;

    /**
     * RowProcessor 实现类,将 ResultSet 的记录转换为 JavaBean
     */
    private final RowProcessor convert;

    /**
     * 创建一个新的 BeanListHandler 实例
     * type:从 handle() 方法返回的 JavaBean 的 Class 类型
     */
    public BeanListHandler(Class<T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 创建一个新的 BeanListHandler 实例
     */
    public BeanListHandler(Class<T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    /**
     * 将 ResultSet 的所有记录转换为一个 List<JavaBean>
     */
    @Override
    public List<T> handle(ResultSet rs) throws SQLException {
        return this.convert.toBeanList(rs, type);
    }
}

使用:

@Test
    public void testBeanListHandler() {
        Connection connection = null;
        try {
            connection = JDBCTools.getConnection();
            String sql = "SELECT * FROM persons";
            List<Person> list = queryRunner.query(connection, sql, new BeanListHandler<>(Person.class));
            list.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

AbstractKeyedHandler 抽象类

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.dbutils.ResultSetHandler;

/**
 * ResultSetHandler 的实现类,返回一个 Map
 * 将 ResultSet 记录转换为对象(Vs),然后将它作为值并以给定键(Ks)存储在Map中 
 */
public abstract class AbstractKeyedHandler<K, V> implements ResultSetHandler<Map<K, V>> {


    /**
     * 将每一行的列转换为 Map
     */
    @Override
    public Map<K, V> handle(ResultSet rs) throws SQLException {
        Map<K, V> result = createMap();
        while (rs.next()) {
            result.put(createKey(rs), createRow(rs));
        }
        return result;
    }

    /**
     * 该工厂方法由 handle() 调用,用来创建一个存储记录的Map
     * 该实现现返回一个 HashMap 实例
     */
    protected Map<K, V> createMap() {
        return new HashMap<K, V>();
    }

    /**
     * 此工厂方法由 handle() 调用,用来从当前的 ResultSet 行中获得 Key
     */
    protected abstract K createKey(ResultSet rs) throws SQLException;

    /**
     * 此工厂方法由 handle() 调用,用来将当前的 ResultSet 行存储在某个对象中
     */
    protected abstract V createRow(ResultSet rs) throws SQLException;

}

KeyedHandler

将结果集中的每一行数据都封装到一个Map里,再把这些Map再存到一个Map里,其key为指定的列

package org.apache.commons.dbutils.handlers;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import org.apache.commons.dbutils.RowProcessor;

public class KeyedHandler<K> extends AbstractKeyedHandler<K, Map<String, Object>> {
    protected final RowProcessor convert;
    protected final int columnIndex;
    protected final String columnName;
    public KeyedHandler() {
        this(ArrayHandler.ROW_PROCESSOR, 1, null);
    }
    public KeyedHandler(RowProcessor convert) {
        this(convert, 1, null);
    }
    public KeyedHandler(int columnIndex) {
        this(ArrayHandler.ROW_PROCESSOR, columnIndex, null);
    }
    public KeyedHandler(String columnName) {
        this(ArrayHandler.ROW_PROCESSOR, 1, columnName);
    }
    private KeyedHandler(RowProcessor convert, int columnIndex,
            String columnName) {
        super();
        this.convert = convert;
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }
    /**
     * 该工厂方法由 handle() 调用,用来在 ResultSet 的当前行获取 Key
     */
    @SuppressWarnings("unchecked")
    @Override
    protected K createKey(ResultSet rs) throws SQLException {
        return (columnName == null) ?
               (K) rs.getObject(columnIndex) :
               (K) rs.getObject(columnName);
    }

    /**
     * 该工厂方法由 handle() 调用,将 ResultSet 的当前行转换为 Map<String, Object>
     */
    @Override
    protected Map<String, Object> createRow(ResultSet rs) throws SQLException {
        return this.convert.toMap(rs);
    }

}

使用:

@Test
    public void testKeyedHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons";
        try {
            connection = JDBCTools.getConnection();
            Map<Integer, Map<String, Object>> map = queryRunner.query(connection, sql, new KeyedHandler<Integer>("id"));
            for (Map.Entry<Integer, Map<String, Object>> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " : " + entry.getValue());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

BeanMapHandler

将结果集中的每一行数据都封装到一个JavaBean里,再把这些JavaBean再存到一个Map里,其key为指定的列

package org.apache.commons.dbutils.handlers;

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

import org.apache.commons.dbutils.RowProcessor;

/**
 * ResultSetHandler 的实现类,返回一个 Map<Object, JavaBean>
 * ResultSet 的记录转换为 JavaBean,并以指定的 Key 保存在 Map 中
 * 如果你有一个主键为 ID 的 Person 数据库表,你可以如下从表中检索记录:
 *
 *  ResultSetHandler<Map<Long, Person>> h = new BeanMapHandler<Long, Person>(Person.class, "id");
 *  Map<Long, Person> found = queryRunner.query("select id, name, age from person", h);
 *  Person jane = found.get(1L); // jane's id is 1
 *  String janesName = jane.getName();
 *  Integer janesAge = jane.getAge();
 *
 * K:返回 Map 的键的类型 
 * V:JavaBean 的类型
 */
public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {

    /**
     * 由 BeanMapHandler 生成的 JavaBean 的 Class 类型
     */
    private final Class<V> type;

    /**
     * RowProcessor 实现类,将 ResultSet 的记录转换为对象
     */
    private final RowProcessor convert;

    /**
     * 列索引,默认值为1
     */
    private final int columnIndex;

    /**
     * 列名
     * columnName 与 columnIndex 只会有一个被用到
     */
    private final String columnName;

    /**
     * 创建一个新的 BeanMapHandler 实例
     * 每一行的第一列的值将作为 Key 保存在 Map 中
     */
    public BeanMapHandler(Class<V> type) {
        this(type, ArrayHandler.ROW_PROCESSOR, 1, null);
    }

    /**
     * 创建一个新的 BeanMapHandler 实例
     */
    public BeanMapHandler(Class<V> type, RowProcessor convert) {
        this(type, convert, 1, null);
    }

    /**
     * 创建一个新的 BeanMapHandler 实例
     */
    public BeanMapHandler(Class<V> type, int columnIndex) {
        this(type, ArrayHandler.ROW_PROCESSOR, columnIndex, null);
    }

    /**
     * 创建一个新的 BeanMapHandler 实例
     */
    public BeanMapHandler(Class<V> type, String columnName) {
        this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName);
    }

    /**
     * 私有构造函数
     * type:createRow() 方法返回的对象的 Class
     * convert:将行装换为 JavaBean 的 RowProcessor 的实现类
     * columnIndex:以索引 columnIndex 的列的值作为 Key(ResultSet.getObject(columnIndex))
     * columnName:以索引 columnName 的列的值作为 Key(ResultSet.getObject(columnName))
     */
    private BeanMapHandler(Class<V> type, RowProcessor convert,
            int columnIndex, String columnName) {
        super();
        this.type = type;
        this.convert = convert;
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    /**
     * 该工厂方法由 handle() 调用,用来在 ResultSet 的当前行获取Key
     */
    @SuppressWarnings("unchecked")
    @Override
    protected K createKey(ResultSet rs) throws SQLException {
        return (columnName == null) ?
               (K) rs.getObject(columnIndex) :
               (K) rs.getObject(columnName);
    }

    /**
     * 该工厂方法由 handle() 调用,将 ResultSet 的当前行转换为对象
     */
    @Override
    protected V createRow(ResultSet rs) throws SQLException {
        return this.convert.toBean(rs, type);
    }

}

使用:

@Test
    public void testBeanMapHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons";
        try {
            connection = JDBCTools.getConnection();
            Map<String, Person> map = queryRunner.query(connection, sql, new BeanMapHandler<String, Person>(Person.class, "name"));
            for (Map.Entry<String, Person> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " : " + entry.getValue());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

KeyedHandler与BeanMapHandler的区别与联系:
都是返回Map,且Map的Key是可自定义的(某个数据库列)
KeyedHandler 返回的Map的Value是:Map<String, Object>
BeanMapHandler 返回的Map的Value是:JavaBean


BaseResultSetHandler 抽象类

需要注意的是:其中的3个抽象类(AbstractKeyedHandlerAbstractListHandlerBaseResultSetHandler),它们的派生类才是可以使用的结果转换器。根据文档的说明,如果官方提供的这些转换类都不能满足你的要求,可以通过继承 BaseResultSetHandler 实现自己的结果集转换器。

使用:

package com.xiya.entity;

import org.apache.commons.dbutils.BaseResultSetHandler;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class MyResultHandler extends BaseResultSetHandler<List<String>> {
    private int indexColumn;

    public MyResultHandler() {
        indexColumn = 1;
    }

    public MyResultHandler(int indexColumn) {
        this.indexColumn = indexColumn;
    }

    @Override
    protected List<String> handle() throws SQLException {
        List<String> list = new ArrayList<>();
        while (this.next()) {
            list.add(handlerRow());
        }
        return list;
    }

    private String handlerRow() throws SQLException {
        return this.getString(indexColumn);
    }
}
@Test
    public void testMyResultHandler() {
        Connection connection = null;
        String sql = "SELECT * FROM persons";
        try {
            connection = JDBCTools.getConnection();
            List<String> list = queryRunner.query(connection, sql, new MyResultHandler(2));
            list.forEach(System.out::println);

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DbUtils.closeQuietly(connection);
        }
    }

关系图:
DbUtils关系图

参考:
http://www.cnblogs.com/myit/p/4272824.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

N3verL4nd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值