我正在写(已经写过)一种通用的数据库查询功能。由于将在不同的地方使用不同的字段名称和不同的列来调用它,因此我想列出一个Map。所以我想我将获取元数据,找到每个列名称并获取列值。但这会抛出ArrayIndexOutOfBoundsException:
try {
ResultSet rs = Query.OpenQuery(conn, sql);
while (rs.next()) {
Map<String, String> map = new HashMap<>();
ResultSetMetaData md = rs.getMetaData();
int cnt = md.getColumnCount();
for (int i = 0; i < cnt; i++) {
String col = md.getColumnName(i);
String val = rs.getString(col);
col = col.toLowerCase();
map.put(col, val);
}
res.add(map);
}
} catch (SQLException e1) {
throw new KDTException("Could not query directconnectionsubmittracking", e1);
}
当我逐步执行该操作时,cnt的值为2。当i为0时,它将在第一次迭代中引发异常,但不应超出范围。不确定为什么会抛出异常。有什么想法吗?
答案 0 :(得分:0)
传递查询听起来像您的系统很容易受到SQL注入攻击。您应该很少基于sql语句进行查询;通常它是一个带有问号的sql语句,以及所有单独传递的参数,使用PreparedStatement将它们联系在一起。否则,您将无法避免SQL注入安全性问题。
有些库已经对此进行了考虑。特别是JDBI和JOOQ;在继续改造这个特殊的车轮之前,我会给他们阅读。
JDBC中的大多数东西都是奇异的1索引,而不是0索引。因此,它是md.getColumnName(i + 1)
或可能将循环从1开始并使用<= cnt
而不是< cnt
。
重新查询每返回的行的列标题很愚蠢;任何给定的结果集都不会在对rs.next()
的调用之间更改标头。一次,而不是每行一次。