写点什么

SQL-DSL 框架之结果集处理

作者:邱学喆
  • 2024-10-25
    广西
  • 本文字数:1775 字

    阅读完需:约 6 分钟

SQL-DSL框架之结果集处理

一. 概述

在使用原生的 jdbc 时,常规开发需要将 ResultSet 对象遍历访问并创建一个对象来承载这个结果。代码如下:

				while (resultSet.next()) {            long id = resultSet.getLong(1);            String name = resultSet.getString(2);            int age = resultSet.getInt(3);            Sex sex =  Sex.valueOf(resultSet.getString(4));            Student student = new Student();            student.setId(id);            student.setName(name);            student.setAge(age);            student.setSex(sex);            .....        }
复制代码

在后面的章节中,通过罗列各种场景,逐步对代码进行调整,以满足各种场景的使用;在过程中会运用到抽象思维以及设计模式来进行。

二. ResultSet 抽象处理

遍历 ResultSet 获取数据进行封装成 java 对象,具体如何封装,可以进行抽象化。这时就可以设计一个接口来抽象化,由子类实现不同类型的封装处理,代码如下:

public interface ResultTransformer<T> {    List<T> transform(ResultSet rs);}
复制代码

三. ColumnTypeHandler 抽象处理

在遍历获取表字段值时都需要根据不同类型从而调用 ResultSet 对象中不同的方法,例如 getString()、getInt()等;因此可以抽象成一个接口 ColumnTypeHandler;

public interface ColumnTypeHandler<T> {  	Class<T> getJavaType();    T getValue(ResultSet rs, String labelName) throws SQLException;}
复制代码

3.1 TypeMapping 门户

在遍历过程,需要匹配类型从而找到对应的 ColumnTypeHandler,如果使用 if 语句,代码将及其难看,因此采用 Map 集合形式来替换。如果 Map 集合以及匹配动作放到 ResultSet 子类,有很强的耦合。因此增加一个中间类来专门处理这个 Map 集合,其大体提供注册 Type 处理器,查找 Type 处理器等功能。代码如下:

public final class TypeMapping {    private static final Map<Class<?>, ColumnTypeHandler<?>> defaultTypes = new HashMap<Class<?>,ColumnTypeHandler<?>>();
private final Map<Class<?>,ColumnTypeHandler<?>> typeByClass = new HashMap<Class<?>,ColumnTypeHandler<?>>(); static { registerDefault(new IntegerColumnTypeHandler()); registerDefault(new StringColumnTypeHandler()); registerDefault(new LongColumnTypeHandler()); } private static void registerDefault(ColumnTypeHandler<?> type) { defaultTypes.put(type.getJavaType(), type); }
private <T> ColumnTypeHandler<T> getDefault(Class<T> clazz){ return (ColumnTypeHandler<T>) defaultTypes.get(clazz); } public <T> ColumnTypeHandler<?> getType(Class<T> clazz) { ColumnTypeHandler<?> handler = typeByClass.get(clazz); if (handler == null) { return getDefault(clazz); } return (ColumnTypeHandler<T>) handler; } public void register(ColumnTypeHandler<?> type) { typeByClass.put(type.getJavaType(), type); }}
复制代码

四. 配置类

TypeMapping 对象具有配置特性,也就是需要开发者注册定制化的处理器。后续会有很多诸如此类的功能需要配置的,如果分别去设置的化,会增加开发者的记忆负担。因此增加一个中间类,将这些类全部收拢起来,统一提供配置方法。

public final class Configuration {    private TypeMapping typeMapping = new TypeMapping();
public void register(ColumnTypeHandler<?> type) { typeMapping.register(type); }
public TypeMapping getTypeMapping() { return typeMapping; }}
复制代码

五. 总结

经过上面的抽象化,相关实现类被隐藏,感兴趣的可以自行补充(相对比较简单),待后续完整实现 SQL-DSL 后开源出来;

上面的测试用例的经过简化后,测试代码如下:

				Configuration configuration = new Configuration();				//注册Sex类型的处理器        configuration.register(new EnumColumnTypeHandler<Sex>(Sex.class));        BeanResultTransformer<Student> transformer = new BeanResultTransformer<>(Student.class, configuration);        List<Student> students = transformer.transform(rs);
复制代码


用户头像

邱学喆

关注

签约作者;计算机原理的深度解读,源码分析 2018-08-26 加入

在IT领域keep Learning。要知其然,也要知其所以然。原理的爱好,源码的阅读。输出我对原理以及源码解读的理解。个人的仓库:https://gitee.com/Michael_Chan

评论

发布
暂无评论
SQL-DSL框架之结果集处理_JDBC_邱学喆_InfoQ写作社区