出现的问题
最近有个特殊需求,又用起了最原始的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();
sort是别名,ORDINAL_POSITION是原始名字,这样别名就失效了。
解决方案
解决方案就是打开开关:useOldAliasBehavior,方法就是在jdbc设置url的时候加上参数 useOldAliasMetadataBehavior=true
注意:本文归作者所有,未经作者允许,不得转载