调用fetch()后如何美观打印org.jooq.impl.ResultImpl查询结果?
解决jOOQ ResultImpl 美观打印带表头(含重复字段)的方案
要实现类似Apache Spark show()的表格打印效果,无需手动指定字段名,同时兼容重复字段名,可通过以下步骤实现:
核心思路
- 完整获取所有字段名:利用
ResultImpl.fields()方法拿到所有Field元数据并提取名称,避开intoMap()的重复字段冲突问题。 - 提取行数据:用
intoLists()获取每行原始数据,统一转为字符串处理,null值显示为"null"。 - 动态计算列宽:根据表头和每行数据的最长长度自动调整列宽,保证表格对齐。
- 格式化拼接表格:按指定样式生成分隔线、表头行、数据行,最终打印输出。
完整实现代码
import org.jooq.Field; import org.jooq.impl.ResultImpl; import java.util.List; import java.util.stream.Collectors; public class JooqResultPrinter { public static void printResult(ResultImpl<?> result) { if (result.isEmpty()) { System.out.println("Empty result"); return; } // 获取所有表头字段名(支持重复字段) List<String> headers = result.fields().stream() .map(Field::getName) .collect(Collectors.toList()); // 将每行数据转为字符串列表,null显示为"null" List<List<String>> rows = result.intoLists().stream() .map(row -> row.stream() .map(obj -> obj == null ? "null" : obj.toString()) .collect(Collectors.toList())) .collect(Collectors.toList()); // 计算每列的最大宽度(表头+数据的最长长度,额外加2个空格边距) int[] columnWidths = new int[headers.size()]; for (int i = 0; i < headers.size(); i++) { columnWidths[i] = headers.get(i).length() + 2; for (List<String> row : rows) { int valLength = row.get(i).length() + 2; if (valLength > columnWidths[i]) { columnWidths[i] = valLength; } } } // 构建分隔线 StringBuilder separator = new StringBuilder("+"); for (int width : columnWidths) { separator.append("-".repeat(width)).append("+"); } // 打印顶部分隔线 System.out.println(separator); // 打印表头行(左对齐) StringBuilder headerRow = new StringBuilder("|"); for (int i = 0; i < headers.size(); i++) { headerRow.append(String.format(" %-" + (columnWidths[i] - 1) + "s|", headers.get(i))); } System.out.println(headerRow); // 打印表头下方分隔线 System.out.println(separator); // 打印数据行:数字右对齐,其他内容左对齐 for (List<String> row : rows) { StringBuilder dataRow = new StringBuilder("|"); for (int i = 0; i < row.size(); i++) { String value = row.get(i); boolean isNumeric = value.matches("-?\\d+(\\.\\d+)?"); if (isNumeric) { dataRow.append(String.format(" %" + (columnWidths[i] - 1) + "s|", value)); } else { dataRow.append(String.format(" %-" + (columnWidths[i] - 1) + "s|", value)); } } System.out.println(dataRow); } // 打印底部分隔线 System.out.println(separator); } }
使用方式
// 假设已通过jOOQ的fetch()获取ResultImpl实例 ResultImpl<?> result = (ResultImpl<?>) dslContext.select(...) .from(YOUR_TABLE) .fetch(); // 调用打印方法 JooqResultPrinter.printResult(result);
效果说明
- 自动适配表头(含重复字段名)和数据长度,生成整齐的表格。
- 表头左对齐,数字类型数据右对齐,非数字左对齐,与你给出的示例格式完全匹配。
- 空结果会友好提示
Empty result。
内容的提问来源于stack exchange,提问作者Takis
相关产品推荐
相关产品推荐

