jdbc字段映射:别名失效问题 useOldAliasBehavior

Published on 2023-04-18 10:38 in 分类: 随笔 with 狂盗一枝梅
分类: 随笔

出现的问题

最近有个特殊需求,又用起了最原始的jdbc读数据库,为了使用方便,做了个自定义的反序列化方法

@Override
    public List<T> handle(ResultSet rs) {
        List<T> list = new ArrayList<T>();
        try {
            ResultSetMetaData rsdm = rs.getMetaData();
            int columnNum = rsdm.getColumnCount();
            while (rs.next()) {
                T t = clazz.newInstance();
                for (int i = 0; i < columnNum; i++) {
                    String columnName = rsdm.getColumnName(i + 1);
                    Method method = methodMap.get(columnName);
                    Object obj = rs.getObject(columnName);
                    if (Objects.isNull(method)) {
                        String setMethodName = StrUtil.toCamelCase("set_" + columnName);
                        for (Method item : clazz.getDeclaredMethods()) {
                            String name = item.getName();
                            if (name.equals(setMethodName)) {
                                try {
                                    item.invoke(t, obj);
                                    break;
                                } catch (Exception e) {
                                    log.error("反序列化字段 {} 失败", columnName);
                                }
                            }
                        }
                        continue;
                    }
                    try {
                        method.invoke(t, obj);
                    } catch (Exception e) {
                        log.error("反序列化字段 {} 失败", columnName);
                    }
                }
                list.add(t);
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return list;
    }

但是,在

Object obj = rs.getObject(columnName);

这行代码报了错,提示columnName没找到,但是不可能啊,因为columnName是这么查出来的

String columnName = rsdm.getColumnName(i + 1);

该方法如下

    public String getColumnName(int column) throws SQLException {
        try {
            if (this.useOldAliasBehavior) {
                return this.getField(column).getName();
            } else {
                String name = this.getField(column).getOriginalName();
                return name == null ? this.getField(column).getName() : name;
            }
        } catch (CJException var4) {
            throw SQLExceptionsMapping.translateException(var4, this.exceptionInterceptor);
        }
    }

这里有个开关useOldAliasBehavior,开关打开,则走this.getField(column).getName();逻辑,否则走下面的逻辑

String name = this.getField(column).getOriginalName();
return name == null ? this.getField(column).getName() : name;

经过debug,发现useOldAliasBehavior为false,走了下面的逻辑,所以最终取的this.getField(column).getOriginalName();

image-20230418100534992

sort是别名,ORDINAL_POSITION是原始名字,这样别名就失效了。

解决方案

解决方案就是打开开关:useOldAliasBehavior,方法就是在jdbc设置url的时候加上参数 useOldAliasMetadataBehavior=true

在这里插入图片描述


#jdbc
目录