You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:49:47