JDBC 将 ResultSet 格式化为表格字符串?

JDBC format ResultSet as tabular string?

当我在 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对象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

使用 ResultSet.getMetaData() 了解每一列和列数并相应地设计 table。

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

    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();
    }