# 背景介绍

在写课设的时候呢,有一个需求是将数据库的数据输出到控制台,最好是格式化输出。

刚开始的时候我使用的方法是使用 select 语句讲数据拿到 ResultSet 中,之后将数据一条一条的放进对象中,之后放进 Arraylist 中来遍历输出。这种方法的效率较低,占用的时间空间都比较大。于是开始寻找一些方便好用的格式化输出 ResultSet 数据的方法,最终在参考了一些资料后整理出了这个方法。

# 需求描述

MySQL 的查询语句输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mysql> select * from student;
+------------+-----------+-----------+
| id | name | phone |
+------------+-----------+-----------+
| 2007040901 | 小亮 | 789789789 |
| 2007040902 | 小白 | 852852852 |
| 2007040903 | 小明 | 123123123 |
| 2007040904 | 小红 | 456456456 |
| 2007040905 | 大飞 | 456645564 |
| 2007041001 | 小青 | 123456789 |
| 2007041002 | 小飞 | 321654987 |
| 2007041003 | 小跑 | 963852741 |
| 2007041004 | 大白 | 789789789 |
| 2007041101 | 小王 | 111222333 |
| 2007041102 | 小星 | 444555666 |
| 2007041103 | 小义 | 777888999 |
| 2007041104 | 萧山 | 111444777 |
| 2007041105 | 大王 | 123123123 |
| 2007041201 | 赵小花 | 222555888 |
| 2007041202 | 赵大花 | 333666999 |
| 2007041203 | 赵老花 | 159357123 |
| 2007041204 | 赵仙花 | 623847456 |
| 2007041205 | 大力 | 915915159 |
| 2007041301 | 郭小凯 | 159159159 |
| 2007041302 | 郭大凯 | 357357357 |
| 2007041303 | 郭老凯 | 852852852 |
| 2007041304 | 郭仙凯 | 963963963 |
| 2007041305 | 大明 | 357537753 |
+------------+-----------+-----------+
24 rows in set (0.00 sec)

使用 JDBC 执行上述的查询语句,将结果集中的查询结果以表格的形式打印出来。

# 思路

  • 通过结果集的元数据可以知道结果集中的列数,和列名.
  • 然后遍历结果集,分别统计每一列中的最大字符数。
  • 然后通过 System.out.printf() 方法进行格式化输出。

# 具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

/**
* 结果集打印机.将结果集中的数据打印成表格.
*/
public class ResultSetPrinter {
public static void printResultSet(ResultSet rs) throws SQLException {
ResultSetMetaData resultSetMetaData = rs.getMetaData();
// 获取列数
int ColumnCount = resultSetMetaData.getColumnCount();
// 保存当前列最大长度的数组
int[] columnMaxLengths = new int[ColumnCount];
// 缓存结果集,结果集可能有序,所以用ArrayList保存变得打乱顺序.
ArrayList<String[]> results = new ArrayList<>();
// 按行遍历
while (rs.next()) {
// 保存当前行所有列
String[] columnStr = new String[ColumnCount];
// 获取属性值.
for (int i = 0; i < ColumnCount; i++) {
// 获取一列
columnStr[i] = rs.getString(i + 1);
// 计算当前列的最大长度
columnMaxLengths[i] = Math.max(columnMaxLengths[i], (columnStr[i] == null) ? 0 : columnStr[i].length());
}
// 缓存这一行.
results.add(columnStr);
}
printSeparator(columnMaxLengths);
printColumnName(resultSetMetaData, columnMaxLengths);
printSeparator(columnMaxLengths);
// 遍历集合输出结果
Iterator<String[]> iterator = results.iterator();
String[] columnStr;
while (iterator.hasNext()) {
columnStr = iterator.next();
for (int i = 0; i < ColumnCount; i++) {
// System.out.printf("|%" + (columnMaxLengths[i] + 1) + "s", columnStr[i]);
System.out.printf("|%" + columnMaxLengths[i] + "s", columnStr[i]);
}
System.out.println("|");
}
printSeparator(columnMaxLengths);
}

/**
* 输出列名.
*
* @param resultSetMetaData 结果集的元数据对象.
* @param columnMaxLengths 每一列最大长度的字符串的长度.
* @throws SQLException
*/
private static void printColumnName(ResultSetMetaData resultSetMetaData, int[] columnMaxLengths) throws SQLException {
int columnCount = resultSetMetaData.getColumnCount();
for (int i = 0; i < columnCount; i++) {
// System.out.printf("|%" + (columnMaxLengths[i] + 1) + "s", resultSetMetaData.getColumnName(i + 1));
System.out.printf("|%" + columnMaxLengths[i] + "s", resultSetMetaData.getColumnName(i + 1));
}
System.out.println("|");
}

/**
* 输出分隔符.
*
* @param columnMaxLengths 保存结果集中每一列的最长的字符串的长度.
*/
private static void printSeparator(int[] columnMaxLengths) {
for (int i = 0; i < columnMaxLengths.length; i++) {
System.out.print("+");
// for (int j = 0; j < columnMaxLengths[i] + 1; j++) {
for (int j = 0; j < columnMaxLengths[i]; j++) {
System.out.print("-");
}
}
System.out.println("+");
}

}


# 测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.sql.*;

public class Test {
private static String driver = "com.mysql.cj.jdbc.Driver";
private static String URL = "jdbc:mysql://localhost:3306/student_information?useUnicode=true&characterEncoding=utf-8";
private static String user = "root";
private static String password = "root";

/**
* JDBC测试.
*/
private static void JDBCexample() {
// 1.加载数据库驱动
try {

Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
testStatement();
}

/**
* 测试Statement的用法.
*/
private static void testStatement() {
try (// 2.打开数据库连接
Connection conn = DriverManager.getConnection(URL, user, password);
// 3.创建语句
Statement stmt = conn.createStatement()) {
// 模拟SQL注入
testSqlInjecton(stmt);

} catch (SQLException sqle) {
System.out.println("SQLException : " + sqle);
}
}

/**
* 模拟SQL注入.
*
* @param stmt Statement对象.
* @throws SQLException
*/
private static void testSqlInjecton(Statement stmt) throws SQLException {
String sql = "select * from student";
ResultSet rs = stmt.executeQuery(sql);
ResultSetPrinter.printResultSet(rs);
}

public static void main(String[] args) {
JDBCexample();
}
}

# 运行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
+----------+---+---------+
| id|name| phone|
+----------+---+---------+
|2007040901| 小亮|789789789|
|2007040902| 小白|852852852|
|2007040903| 小明|123123123|
|2007040904| 小红|456456456|
|2007040905| 大飞|456645564|
|2007041001| 小青|123456789|
|2007041002| 小飞|321654987|
|2007041003| 小跑|963852741|
|2007041004| 大白|789789789|
|2007041101| 小王|111222333|
|2007041102| 小星|444555666|
|2007041103| 小义|777888999|
|2007041104| 萧山|111444777|
|2007041105| 大王|123123123|
|2007041201|赵小花|222555888|
|2007041202|赵大花|333666999|
|2007041203|赵老花|159357123|
|2007041204|赵仙花|623847456|
|2007041205| 大力|915915159|
|2007041301|郭小凯|159159159|
|2007041302|郭大凯|357357357|
|2007041303|郭老凯|852852852|
|2007041304|郭仙凯|963963963|
|2007041305| 大明|357537753|
+----------+---+---------+

# 提示

在使用时可以根据具体情况适当的做一些微调,以便达到想要的效果。