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

将多个数据库表数据展示到JTable时遇到问题求助

问题描述

我接触Java+SQL开发时间不长,为实现“把多个数据库表数据展示到JTable”这个功能折腾了好几周,现在卡壳了——要么只能显示单个表,要么三个表的数据乱堆在一起,滚动面板的表头还会出现所有表的ID列,求方向上的指导。

代码核心问题分析
  1. 表格模型复用导致数据堆叠
    你在循环创建表格时,复用了JTable默认的DefaultTableModel,没有每次循环都新建模型,之前表的数据会残留到下一个表的模型里,最终导致数据混乱堆叠。

  2. 表头设置位置错误
    把model.setColumnIdentifiers(colName);放在了列名遍历的内部,每遍历一列就设置一次表头,多次覆盖后表头会出现混乱。

  3. 表名获取逻辑错误
    使用mD.getTableName(k+1)获取表名是错误的,循环索引k和ResultSetMetaData中列对应的表索引没有关联,会导致标签页名称错误。

修正后的关键代码

1. 修改getData方法,同时存储表名和数据

将原本只存CachedRowSet的集合,改成同时存储表名和对应数据,避免后续获取表名出错:

public static ArrayList<Map<String, Object>> getData(String url, String database, String user, String pass) {
    PreparedStatement stat, stat2;
    ResultSet data, dbName;
    String dbURLString = "jdbc:mysql://" + url + "/" + database;
    String dbSql = "Show tables from " + database;
    String sqlState;

    ArrayList<Map<String, Object>> dataList = new ArrayList<>();

    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        try (Connection conn = DriverManager.getConnection(dbURLString, user, pass)) {
            stat = conn.prepareStatement(dbSql);
            dbName = stat.executeQuery();
            while (dbName.next()) {
                RowSetFactory fact = RowSetProvider.newFactory();
                CachedRowSet crs = fact.createCachedRowSet();
                String tableName = dbName.getString("Tables_in_" + database);
                sqlState = "Select * from " + tableName + ";";
                stat2 = conn.prepareStatement(sqlState);
                data = stat2.executeQuery();
                crs.populate(data);
                
                // 封装表名和对应数据
                Map<String, Object> tableData = new HashMap<>();
                tableData.put("tableName", tableName);
                tableData.put("data", crs);
                dataList.add(tableData);
            }
            conn.close();
            loginButton.Instance.dispose();
            return dataList;
        }
    } catch (SQLException | ClassNotFoundException ex) {
        Logger.getLogger(DatabaseSchema2.class.getName()).log(Level.SEVERE, "Failed to get data", ex);
        loginButton.Instance.errLabel.setVisible(true);
    }
    return null;
}

2. 修改addPane方法,正确创建独立的表格和模型

每次循环都新建DefaultTableModel,确保每个表的数据和表头独立:

public static JTabbedPane addPane() throws SQLException {
    String user = loginButton.Instance.username;
    String pass = loginButton.Instance.password;
    String url = loginButton.Instance.server;
    String database = loginButton.Instance.database;
    JTabbedPane pane = new JTabbedPane(JTabbedPane.TOP);
    ArrayList<Map<String, Object>> dataList = getData(url, database, user, pass);
    
    if(dataList == null || dataList.isEmpty()){
        return pane;
    }
    
    for (Map<String, Object> tableData : dataList) {
        String tableName = (String) tableData.get("tableName");
        CachedRowSet data = (CachedRowSet) tableData.get("data");
        
        // 每次循环新建模型,避免数据污染
        DefaultTableModel model = new DefaultTableModel();
        JTable table = new JTable(model);
        JScrollPane scroll = new JScrollPane(table);
        
        ResultSetMetaData mD = data.getMetaData();
        int columns = mD.getColumnCount();
        String[] colName = new String[columns];
        
        // 先遍历获取所有列名
        for (int j = 0; j < columns; j++) {
            colName[j] = mD.getColumnName(j + 1);
        }
        // 统一设置表头
        model.setColumnIdentifiers(colName);
        
        // 添加数据行
        while (data.next()) {
            ArrayList<String> rows = new ArrayList<>();
            for (int i = 0; i < columns; i++) {
                String row = data.getString(i + 1);
                rows.add(row);
            }
            model.addRow(rows.toArray());
        }
        
        pane.addTab(tableName, scroll);
    }
    return pane;
}
额外优化建议
  • 给JTable添加自动列宽调整:table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);,提升显示体验。
  • 可以对getString返回的null值做处理,比如替换成空字符串,避免表格显示null。

内容的提问来源于stack exchange,提问作者Michael Richards

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:24:53