【问题标题】:JDBC format ResultSet as tabular string? [closed]JDBC格式ResultSet作为表格字符串? [关闭]
【发布时间】:2016-12-02 01:38:17
【问题描述】:

当我在 MySQL 命令行界面中查询数据库时,我会得到一些漂亮的美化表格输出:

mysql> select * from users;
+------------+--------------------------------------+------------+
| IGN        | UUID                                 | AdminLevel |
+------------+--------------------------------------+------------+
| GamerBoy   | 0fcba4a5-f039-4771-ae22-bf203ed89c1c |          3 |
+------------+--------------------------------------+------------+

现在,在 java 中,我必须使用 ResultSet 来存储查询结果,这是我目前拥有的代码:

String query = String.join(" ", Arrays.copyOfRange(args, 2, args.length));
System.out.println("Querying the database with: " + query);
try {
  Statement stmt = dbConnection.createStatement();
  ResultSet rs = stmt.executeQuery(query);
  System.out.println("Query parsed successfully!");
  /* What need to go here? I want to output the result of the query
   * in the same way that the MySQL tool would - some prettified String.
   */
} catch (SQLException exception) {
  System.out.println("Query failed: " + exception.getMessage()) ;
}

我如何获得一个包含 MySQL 将给我的输出类型的字符串?


基本上,我想制作一个可以查询数据库的 java 程序——查询每次都可以不同,它是用户选择的——然后以 MySQL 使用的简洁表格格式输出查询结果。

我该怎么做?

【问题讨论】:

  • ResultSet 不保留 MySQL 使用的格式。如果您希望它看起来像 MySQL,您必须自己创建该格式。
  • @SusannahPotts 我刚开始使用 JDBC,对我来说,问题并不像你想象的那么简单;我什至不知道用户正在查询什么表,更不用说列的名称或数量等了。
  • 我从来没有说过它是微不足道的,或者我认为它是微不足道的。我只是说 ResultSet 不保留格式,并且您希望您必须创建任何格式。
  • 有许多库可以帮助完成从 ResultSet 转换数据的繁琐工作。示例包括jOOQSQLContainer 中的Vaadin (demo)、RowSet 与各种实现的接口等等。这是一个很大的领域。但首先要自己用纯 Java 代码做一些事情来获得导向。

标签: java mysql database jdbc resultset


【解决方案1】:

使用ResultSet.getMetaData() 找出每列和列的编号,并相应地设计表。

这是一个脏的未经测试的样本。

    private String processResultSet(ResultSet rs) throws Exception
    {
        StringBuilder sb = new StringBuilder();

        ResultSetMetaData rsmd = rs.getMetaData();
        int totalCols = rsmd.getColumnCount();
        int[] colCounts = new int[totalCols];
        String[] colLabels = new String[totalCols];
        for(int i = 0; i < totalCols; i++)
        {
            colCounts[i] = rsmd.getColumnDisplaySize(i+1);
            colLabels[i] = rsmd.getColumnLabel(i+1);
            if(colLabels[i].length() > colCounts[i])
            {
                colLabels[i] = colLabels[i].substring(0, colCounts[i]);
            }
            sb.append(String.format("| %"+ colCounts[i] +"s ", colLabels[i]));
        }
        sb.append("|\n");

        String horizontalLine = getHorizontalLine(colCounts);
        while(rs.next())
        {
            sb.append(horizontalLine);
            for(int i = 0; i < totalCols; i++)
            {
                sb.append(String.format("| %"+ colCounts[i] +"s ",rs.getString(i+1)));
            }
            sb.append("|\n");

        }


        return (getHorizontalLine(colCounts)+sb.toString());
    }

    private String getHorizontalLine(int[] colCounts)
    {
        StringBuilder sb = new StringBuilder();

        for(int i = 0; i < colCounts.length; i++)
        {
            sb.append("+");
            for(int j = 0; j < colCounts[i] + 2; j++)
            {
                sb.append("-");
            }
        }
        sb.append("+\n");

        return sb.toString();
    }

【讨论】:

  • 这似乎很有用...您介意发布一个快速而肮脏的示例,说明如何循环遍历每个 ResultSet 条目,然后遍历每个列吗?
  • @theonlygusti 刚刚添加了它。
  • 这只是导致我的服务器崩溃....一个滴答声太长了,猜测它无限循环。
  • 可能是因为某些表格条目包含新行?
  • @theonlygusti 您可能在该查询中提取了太多数据,并且出现内存不足错误。而且由于这是一个快速而肮脏的代码,我没有处理任何边缘情况。您应该修改它以满足您的要求。如果您喜欢这个答案,可以将其标记为已接受;)
【解决方案2】:

你需要自己处理ResultSet对象rs

while(rs.next()){
  String ign = rs.getString("IGN");
  // ... get uuid and admin level
  System.out.println(ign + uuid ...);
}

如果您不知道列名,请使用ResultSet#getMetaData()

ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount() ; // returns the number of columns
for(int i = 1; i < columnCount + 1; i++){
    rsmd.getColumnName(i);
}

请注意,列是 1 索引的,也就是说,第一个列名称是:rsmd.getColumnName(1);

检查Java8 ResultSetMetaData API

【讨论】:

  • 但我不知道潜在的字段(列名?) - 我什至不知道用户将从哪个表查询。
  • @theonlygusti 查看我的更新
  • 谢谢你让我开始,我最终也不得不使用ResultSetMetaData#getColumnTypeName方法来检查我是否应该使用getStringgetInt等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多