如何从Java ResultSet中确定列数?

4

我希望在 jtable 中显示 SQL 数据。第一步是创建一个 tablemodel

public DefaultTableModel createTableModel(String sqlStatement) {
    int rowCount       = 0;
    int colCount       = 0;
    Vector data        = new Vector();
    Vector columnnames = new Vector();
    String sql = sqlStatement;
    try {
        open();

        ResultSet rs = befehl.executeQuery(sql);
        ResultSetMetaData metaData = rs.getMetaData();
        for(int i = 1; i<=metaData.getColumnCount();i++)
            columnnames.add(metaData.getColumnName(i));
        DefaultTableModel model = new DefaultTableModel(null,columnnames);
        close();
        return model;
    } catch (SQLException e) {
        e.printStackTrace();
        close();
        return null;
    }
}

如果我的SQL语句选择整个表,则可以正常工作:SELECT * FROM test;,但是如果我只想显示前两列:Select ColumnName1, ColumName2 from test;,我会得到一个ArrayIndexOutOfBoundsException。我一直认为columncount取决于resultSet,而resultSet取决于SQL语句。我该如何获得正确的columncount

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 >= 2
at java.util.Vector.elementAt(Vector.java:470)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java‌​:294)
at sun.swing.SwingUtilities2.convertColumnIndexToModel(SwingUtilities2.java:1841)
at javax.swing.JTable.convertColumnIndexToModel(JTable.java:2585)
at javax.swing.JTable.getValueAt(JTable.java:2720) at Main.KassePanel.<init>(KassePanel.java:186)
at Main.Main.<init>(Main.java:36) at Main.Main.main(Main.java:20)

什么是RMDS?MySQL? - Paul Vargas
2
请发布堆栈跟踪。 - PeakGen
如果您分享实际创建JTable的代码片段可能会有所帮助。显然,这段代码没有任何问题。 - Ivo
不,表格模型有两列,但是你的调用代码正在尝试访问更多列。 - user207421
你的代码没有问题,很好。你对 select * 的假设是错误的——元数据是基于执行的查询的。 - Bohemian
显示剩余3条评论
1个回答

1
你应该使用 DatabaseMetaData 而不是 ResultSetMetaData。我已经完成了一个名为 dbproxy 的 Java 项目,旨在操作和访问关系数据库的结构(元数据)。我很快就会将它变成一个开源项目。请查看我的代码:
@Override
public List<ColumnDetail> getColumns(String table) throws SQLException {
    List<ColumnDetail> columnList = new ArrayList<ColumnDetail>();
    ResultSet resultSet = null;
    String catalog = getCatalog();
    String schema = getSchema();

    try {
        DatabaseMetaData databaseMetaData = connection.getMetaData();
        if(databaseMetaData == null) {
            return columnList;
        }
        resultSet = databaseMetaData.getColumns(catalog, schema, table, null);
        if(resultSet == null) {
            return columnList;
        }
        while(resultSet.next()) {
            columnList.add(extractColumnDetail(resultSet));
        }
    }
    catch (SQLException e) {
        throw new SQLException("Could not get columns: " + e.toString());
    }
    catch (Exception e) {
        throw new SQLException("Could not get columns: " + e.toString());
    }
    finally {
        DatabaseUtil.close(resultSet);
    }
    return columnList;
}  

参考资料 Apress.JDBC.Metadata.MySQL.and.Oracle.Recipes.A.Problem.Solution.Approach.Mar.2006


为什么?数据库元数据不知道任何特定查询返回多少列。 - user207421
我猜测SQL语句是通过某些逻辑动态生成的,而不是硬编码生成的。因此,在生成SQL语句时应该确定选择列表,而不是在SQL执行时确定。 - Henry Leu
没错,那么 DatabaseMetaData 怎么知道任意 SQL 查询中会有多少列呢?你认为这个建议解决了什么问题? - user207421
当然,在原问题点上,我的答案无法解决它。所以我要删除它。我建议你在SQL生成时确定列,而不是在SQL执行时。 - Henry Leu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接