如何用Java通过SHOW Tables命令列出多MySQL数据库及其表?代码异常
问题分析与修复方案
首先,你的代码核心问题在于复用了同一个Statement对象执行多个查询。JDBC规范里明确规定:一个Statement对象同时只能打开一个ResultSet——当你用同一个stmt执行SHOW TABLES查询时,之前获取数据库列表的resultSet会被自动关闭,导致循环只处理第一个数据库就终止了。
另外还有个小细节问题:connect方法里的URL拼接错误,当传入dbName时,你写的是url = "jdbc:mysql://x:x"+ dbName;,这里少了一个斜杠,应该是url = "jdbc:mysql://x:x/" + dbName;,不过这个不是导致无法获取第二个数据库的直接原因,但也得修正。
修复后的完整代码
修正connectMySQL类
public class connectMySQL implements serverConnection{ Connection conn; // 移除全局stmt成员变量,避免复用冲突 public void connect(String dbName){ String url; try { if(dbName.equals("")){ url = "jdbc:mysql://x:x/"; } else{ // 修正URL拼接,添加必要的斜杠 url = "jdbc:mysql://x:x/" + dbName; } String username = "x"; String password = "x"; conn = DriverManager.getConnection(url,username,password); } catch (SQLException ex) { System.out.println("An error occurred. Maybe user/password is invalid"); ex.printStackTrace(); } } }
修正listInf类
public class listInf extends connectMySQL implements listInfrastructure { public void list() { String dbName; try{ connect(""); // 创建专门用于查询数据库列表的Statement Statement dbStmt = conn.createStatement(); String str = "SHOW DATABASES"; ResultSet resultSet = dbStmt.executeQuery(str); while(resultSet.next()){ dbName = resultSet.getString("Database"); if(!dbName.contains("schema") && !dbName.equals("mysql")){ // 按照你期望的格式输出数据库名 System.out.print(dbName + ": "); // 为每个数据库的表查询创建独立的Statement Statement tableStmt = conn.createStatement(); ResultSet rs = tableStmt.executeQuery("SHOW TABLES IN " + dbName); boolean isFirstTable = true; while (rs.next()) { if(!isFirstTable){ System.out.print(", "); } System.out.print(rs.getString("Tables_in_" + dbName)); isFirstTable = false; } // 输出完当前数据库的表后换行 System.out.println("."); // 及时关闭当前表查询的资源 rs.close(); tableStmt.close(); } } // 关闭数据库列表查询的资源 resultSet.close(); dbStmt.close(); // 关闭数据库连接,避免资源泄漏 conn.close(); } catch(SQLException e){ System.out.println("Error"); e.printStackTrace(); } } }
关键改动说明
- 移除了全局
stmt成员变量,改用局部独立的Statement对象分别处理数据库列表和表查询,避免ResultSet被意外关闭; - 修正了URL拼接的斜杠问题,保证数据库连接的正确性;
- 调整输出逻辑,完全匹配你期望的格式;
- 添加了资源关闭代码,避免数据库连接泄漏。
预期输出
运行修正后的代码,你会得到如下格式的输出:
Database_Services: MySQL_Database_Service, MSSQL_Database_Service. Directory_Services: Active_Directory, OpenLDAP.
内容的提问来源于stack exchange,提问作者Oğuz Öztınaz
相关产品推荐
相关产品推荐

