Java获取指定表列数、列名与列类型的代码问题排查及解决方案
问题修复方案
嘿,我帮你梳理下代码里的问题,这几个点是导致输出不符合预期的关键:
为啥你的代码会出问题?
- 列数统计错了:你用
rsmd.getColumnCount()拿到的是getColumns返回的元数据结果集自身的列数(比如TABLE_CAT、COLUMN_NAME这些元数据字段的数量),根本不是你要查的表的实际列数。 - 列名/类型只留最后一个:循环遍历列信息的时候,你每次都把新的列名和类型覆盖到同一个变量里,循环结束自然只剩最后一列的数据了。
- 列类型看不懂:直接输出
columnType的int值(比如1对应VARCHAR),谁能一眼看懂啊?得转成可读的类型名称才行。
修正后的完整代码
import java.sql.Types; import java.util.ArrayList; import java.util.List; public void printTableInfo(String tableName) throws DLException{ String catalog = null; String schemaPattern = null; String tableNamePattern = tableName; String columnNamePattern = null; // 用集合存所有列的信息,避免被覆盖 List<String> columnNames = new ArrayList<>(); List<String> columnTypes = new ArrayList<>(); List<String> primaryKeyColumns = new ArrayList<>(); try { DatabaseMetaData dbmd = connection.getMetaData(); // 获取目标表的所有列信息 ResultSet columnResult = dbmd.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); // 遍历每一列,收集名称和可读的类型 while(columnResult.next()) { String colName = columnResult.getString("COLUMN_NAME"); int colTypeInt = columnResult.getInt("DATA_TYPE"); // 把JDBC的int类型转成易懂的字符串 String colTypeName = getReadableJdbcType(colTypeInt); columnNames.add(colName); columnTypes.add(colTypeName); } // 收集主键信息,支持复合主键 ResultSet pkResult = dbmd.getPrimaryKeys(catalog, schemaPattern, tableNamePattern); while(pkResult.next()) { String pkColName = pkResult.getString("COLUMN_NAME"); primaryKeyColumns.add(pkColName); } // 格式化输出信息 System.out.println("Column count: " + columnNames.size()); System.out.println("Column names: " + String.join(", ", columnNames)); System.out.println("Column types: " + String.join(", ", columnTypes)); System.out.println("Primary Keys: " + (primaryKeyColumns.isEmpty() ? "None" : String.join(", ", primaryKeyColumns))); } catch (SQLException sqle) { throw new DLException(sqle, "-> Error in processing data printing (SQLException) to the database at printTableInfo() method."); } } // 辅助方法:把JDBC的int类型常量转成可读的名称 private String getReadableJdbcType(int typeInt) { switch(typeInt) { case Types.VARCHAR: return "VARCHAR"; case Types.INTEGER: return "INTEGER"; case Types.BIGINT: return "BIGINT"; case Types.DATE: return "DATE"; case Types.TIMESTAMP: return "TIMESTAMP"; case Types.BOOLEAN: return "BOOLEAN"; case Types.CHAR: return "CHAR"; case Types.DECIMAL: return "DECIMAL"; case Types.FLOAT: return "FLOAT"; case Types.DOUBLE: return "DOUBLE"; // 你可以根据自己用的数据库,补充更多类型对应的case default: return "UNKNOWN_TYPE(" + typeInt + ")"; } }
关键修改点解释
- 用集合存储列数据:换成
ArrayList来保存每一列的信息,这样循环的时候不会覆盖之前的数据,所有列都能保留下来。 - 正确统计列数:目标表的实际列数就是
columnNames的大小,因为每遍历到一列就往集合里加一个元素。 - 列类型人性化:加了个
getReadableJdbcType方法,把JDBC定义的int类型转换成大家能看懂的字符串,比如把1转成VARCHAR。 - 主键支持复合键:原代码只能拿到最后一个主键,现在用集合可以存储多个主键,符合复合主键的场景。
- 输出更清晰:用
String.join把集合里的元素拼成逗号分隔的字符串,输出的格式更整齐易懂。
内容的提问来源于stack exchange,提问作者Mislav Rukonic
相关产品推荐
相关产品推荐

