【发布时间】:2017-04-20 18:44:38
【问题描述】:
我需要动态 SQL,它接受来自用户的表和列名并在查询中使用它们。现在我用
public Object doSearch(String table, List<String> columns) {
//... some logic
String.format("SELECT %s from %s", String.join(", ", columns), table");
//... some execution and return
}
来源不受信任,因此我想做一个表名和列名的白名单,但该列表发生了变化。有效表的列表严格来说是my_schema 上的表列表,而有效列的列表严格来说是该特定表上的列。
我搜索了 SO 并得到了一个看起来像这样的解决方案:
private boolean validate(String tableName, List<String> columnNames) throws SQLException {
return tableExist(tableName) && columnNames.stream().allMatch(cn -> columnExistsOnTable(tableName, cn));
}
private boolean tableExist(String tableName) throws SQLException {
try (ResultSet rs = connection.getMetaData().getTables(null, schema, tableName, null)) {
while (rs.next()) {
String tName = rs.getString("TABLE_NAME");
if (tName != null && tName.equals(tableName)) {
return true;
}
}
}
return false;
}
private boolean columnExistsOnTable(String tableName, String columnName) {
try (ResultSet rs = connection.getMetaData().getColumns(null, schema, tableName, columnName)) {
while (rs.next()) {
String tName = rs.getString("COLUMN_NAME");
if (tName != null && tName.equals(tableName)) {
return true;
}
}
} catch (SQLException sqle) {
return false;
}
return false;
}
这样安全正确吗?
【问题讨论】:
-
我觉得可以参考this post。您实际上需要获取数据库定义才能解析它并找到您需要的对象。该项目可能会帮助您独立于数据源工作。
标签: java postgresql jdbc