我是靠谱客的博主 机灵吐司,最近开发中收集的这篇文章主要介绍DbUtils源码分析-ResultSetHandler,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

DbUtils除了QueryRunner外,最重要的就是ResultSetHandler及其子类了,他帮我们封装了数据库取回的数据,除了已经提供的常用的BeanHandler, BeanListhandler, ScalarHandler之外,还可以自定义数据处理的方式。


1.ResultSetHandler

//通过这个方法将ResultSet转成需要的类型
public interface ResultSetHandler<T> {
    T handle(ResultSet rs) throws SQLException;
}

2.BeanHandler: 查询结果为一条记录时

public class BeanHandler<T> implements ResultSetHandler<T> {
    //泛型T的具体类型
    private final Class<? extends T> type;
    //行处理器,不指定则默认是BasicRowProcessor
    private final RowProcessor convert;
    /*
    提供空的构造也是可以的,
    可以通过ParameterizedType#getActualTypeArguments()获取泛型的类型信息
    */
    public BeanHandler(Class<? extends T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    public BeanHandler(Class<? extends T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    //即使查询有多条也只返回第一条记录
    @Override
    public T handle(ResultSet rs) throws SQLException {
        /*
        调用BasicRowProcessor#toBean,最后会调用BeanProcessor#toBean
        先实例化bean,通过属性描述器PropertyDescriptor设置相应的值
        */
        return rs.next() ? this.convert.toBean(rs, this.type) : null;
    }
}

eg:
Course course = queryRunner.query(connection, "SELECT * from course where courseid=1", new BeanHandler<Course>(Course.class));

3.BeanListHandler 查询结果存在多条记录时

public class BeanListHandler<T> implements ResultSetHandler<List<T>> {
    private final Class<? extends T> type;
    private final RowProcessor convert;

    public BeanListHandler(Class<? extends T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    public BeanListHandler(Class<? extends T> type, RowProcessor convert){
        this.type = type;
        this.convert = convert;
    }

    @Override
    public List<T> handle(ResultSet rs) throws SQLException {
        //和BeanHandler相似的,只是这个处理多行的记录
        return this.convert.toBeanList(rs, type);
    }
}

eg:
List<Course> courseList = queryRunner.query(connection, "SELECT * from course", new BeanListHandler<Course>(Course.class));

4.ScalarHandler 查询单值,字符串/数字之类的

public class ScalarHandler<T> implements ResultSetHandler<T> {
    private final int columnIndex;
    private final String columnName;
    //默认返回第一列的值
    public ScalarHandler() {
        this(1, null);
    }
    //指定列的序号
    public ScalarHandler(int columnIndex) {
        this(columnIndex, null);
    }
    //指定列名
    public ScalarHandler(String columnName) {
        this(1, columnName);
    }
    //private 没什么用,要不指定列序号,要不指定列名
    private ScalarHandler(int columnIndex, String columnName) {
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T handle(ResultSet rs) throws SQLException {
        //这个比较简单就是调用rs的方法获取对象,其他无非就是判断列名列序号
        //存在多行也只处理第一行的数据
        if (rs.next()) {
            //列名为空根据列序号来
            if (this.columnName == null) {
                return (T) rs.getObject(this.columnIndex);
            }
            //列名不为空根据列名来
            return (T) rs.getObject(this.columnName);
        }
        //查询结果rs没有记录
        return null;
    }
}

eg:
Integer count = queryRunner.query(connection, "SELECT COUNT(*) c1 FROM course", new ScalarHandler<Integer>("c1"));      

5.ArrayHandler 返回第一条记录的所有字段数组

public class ArrayHandler implements ResultSetHandler<Object[]> {
    //BeanHandler/BeanListHandler都是使用这个行处理器
    static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();
    //当rs没有记录时返回这个
    private static final Object[] EMPTY_ARRAY = new Object[0];

    private final RowProcessor convert;

    public ArrayHandler() {
        this(ROW_PROCESSOR);
    }

    public ArrayHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    /*BasicRowProcessor#toArray方法,和ScalarHandler差不多,
    ScalarHandler返回指定列,这里是遍历所有的列放入数组中返回
    */
    @Override
    public Object[] handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toArray(rs) : EMPTY_ARRAY;
    }
}

6.MapHandler 返回第一条记录的map,key=列名 value=列值

public class MapHandler implements ResultSetHandler<Map<String, Object>> {

    private final RowProcessor convert;

    public MapHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    public MapHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }
    /*
    ArrayHandler只将值放入数组,这里还将列名和值放入Map中返回
    */
    @Override
    public Map<String, Object> handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toMap(rs) : null;
    }
}

7.BaseResultSetHandler

public abstract class BaseResultSetHandler<T> implements ResultSetHandler<T> {
    /*......
    可以根据自己的需要处理ResultSet,封装了ResultSet的基本的方法
    */
}

8.AbstractListHandler 也是返回记录列表,和ArrayHandler相识,只是这个类可以对每行记录特殊处理

public abstract class AbstractListHandler<T> implements ResultSetHandler<List<T>> {

    @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;
    }
    //提供抽象的方法对每一行的数据进行处理
    protected abstract T handleRow(ResultSet rs) throws SQLException;
}

9.MapListHandler 返回列表,列表的每一个元素都是Map类型的数据,每个Map代表一行记录,MapHandler 只有一条记录

public class MapListHandler extends AbstractListHandler<Map<String, Object>> {
    private final RowProcessor convert;
    public MapListHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    public MapListHandler(RowProcessor convert) {
        super();
        this.convert = convert;
    }

    //重载的是AbstractListHandler的handleRow,有抽象父类负责循环ResultSet,去add每个Map
    @Override
    protected Map<String, Object> handleRow(ResultSet rs) throws SQLException {
        return this.convert.toMap(rs);
    }
}

10.AbstractKeyedHandler 返回记录的Map结构,和MapHandler相识,只不过可以自定义key的类型而已

public abstract class AbstractKeyedHandler<K, V> implements ResultSetHandler<Map<K, V>> {

    @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;
    }

    protected Map<K, V> createMap() {
        return new HashMap<K, V>();
    }

    //将这个返回值作为Map的key,MapHandler默认是将列名作为key
    protected abstract K createKey(ResultSet rs) throws SQLException;
    //将这个返回值作为Map的value
    protected abstract V createRow(ResultSet rs) throws SQLException;
}

11.KeyedHandler 默认优先列名作为key,若列名为空则取列序号为key

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;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected K createKey(ResultSet rs) throws SQLException {
        return (columnName == null) ?
               (K) rs.getObject(columnIndex) :
               (K) rs.getObject(columnName);
    }

    @Override
    protected Map<String, Object> createRow(ResultSet rs) throws SQLException {
        return this.convert.toMap(rs);
    }
}

12.BeanMapHandler 将查询的结果保存为Bean组装到Map对象中返回

public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> {
    private final Class<V> type;
    private final RowProcessor convert;
    private final int columnIndex;
    private final String columnName;
    //类似不赘述
    public BeanMapHandler(Class<V> type) {
        this(type, ArrayHandler.ROW_PROCESSOR, 1, null);
    }
    public BeanMapHandler(Class<V> type, RowProcessor convert) {
        this(type, convert, 1, null);
    }
    public BeanMapHandler(Class<V> type, int columnIndex) {
        this(type, ArrayHandler.ROW_PROCESSOR, columnIndex, null);
    }
    public BeanMapHandler(Class<V> type, String columnName) {
        this(type, ArrayHandler.ROW_PROCESSOR, 1, 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;
    }

    //通过指定列序号或列名作为Map的Key,Map的值为Bean对象
    @SuppressWarnings("unchecked")
    @Override
    protected K createKey(ResultSet rs) throws SQLException {
        return (columnName == null) ?
               (K) rs.getObject(columnIndex) :
               (K) rs.getObject(columnName);
    }

    @Override
    protected V createRow(ResultSet rs) throws SQLException {
        return this.convert.toBean(rs, type);
    }
}

13.ColumnListHandler 返回某一列的数据

public class ColumnListHandler<T> extends AbstractListHandler<T> {
    private final int columnIndex;
    private final String columnName;
    public ColumnListHandler() {
        this(1, null);
    }
    public ColumnListHandler(int columnIndex) {
        this(columnIndex, null);
    }
    public ColumnListHandler(String columnName) {
        this(1, columnName);
    }
    private ColumnListHandler(int columnIndex, String columnName) {
        super();
        this.columnIndex = columnIndex;
        this.columnName = columnName;
    }

    //返回指定列序号或列名的这一列的数组
    @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);
   }
}

最后

以上就是机灵吐司为你收集整理的DbUtils源码分析-ResultSetHandler的全部内容,希望文章能够帮你解决DbUtils源码分析-ResultSetHandler所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部