【问题标题】:java swing jtable add two table from database in single table [closed]java swing jtable在单个表中从数据库中添加两个表[关闭]
【发布时间】:2017-11-16 06:51:33
【问题描述】:

我有名为 tbl_income 和 tbl_expenses 的表... tbl_income 包含四列四行,tbl_expenses 包含四列三行链接如下图。

我想在下面的 java swing JTable 链接图片中处理单个表。

我怎么能这样......对不起英语不好......

这是我尝试过的:

 DefaultTableModel model = (DefaultTableModel) tbldailybook.getModel();
        try {
            Statement stmt = db.cn.createStatement();
            ResultSet rs = stmt.executeQuery("select * from tblincome,tblexpenses");
            while (rs.next()) {
                model.addRow(new Object[]{rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(6), rs.getString(7), rs.getString(8)});
            }
        } catch (Exception e) {
        }

tblincome 有单行但行回复

【问题讨论】:

  • 两张表之间是否有联系(关系)?
  • 没有任何关系......我在数据库中有两个表,我想在单个 JTable 中加入两个表
  • 所以你有两个基本问题; 1- 如何将两个表中的数据合并到一个结果集中; 2- 如何从数据库中读取数据并在JTable 中显示该数据。这两个问题都不是唯一的,并且在过去被问过更多次,然后我才关心重新计算。在我们尝试帮助之前,您需要做出一些努力来帮助自己。我会先把你的问题分解成可管理的块(就像我列出的两个问题)并独立解决这个问题,结果你会学到一些新东西并解决你自己的问题
  • 我不太同意这位指挥官。两个表之间没有关系,这使得很难使用连接并获得公平的结果。我认为正确的解决方案是分别提取这两个表并在公共TableModel 中使用它们。这并没有让这个问题变得微不足道。
  • @mrmcwolf 因为 SQL 不支持对表进行仲裁连接?单独提取数据仍然需要创建“关系”以便能够显示它 - 大多数数据库系统都能够做到这一点(这是您拥有 join 命令的原因之一) - as a completely out of context example - 事实上,根据 OP 列出的示例this would probably work better

标签: java mysql swing jtable


【解决方案1】:

这是一个单独提取两个表并将它们集成到一个公共TableModel 中的解决方案。

public class MyTableModel extends AbstractTableModel implements TableModel {
    private List<Data> inclomeList;
    private List<Data> expenseList;

    private void setData(List<Data> list, Data data) {
        int rows = getRowCount();
        int row = list.size();
        list.add(data);

        if(row < rows) {
            fireTableRowsUpdated(row, row);
        }
        else {
            fireTableRowsInserted(row, row);
        }
    }

    public void setIncomeData(Data data) {
        if(inclomeList == null) {
            inclomeList = new ArrayList<>();
        }

        setData(inclomeList, data);
    }

    public void setExpenseData(Data data) {
        if(expenseList == null) {
            expenseList = new ArrayList<>();
        }

        setData(expenseList, data);
    }

    @Override
    public String getColumnName(int column) {
        switch (column) {
            case 0:
            case 3:
                return "Date";

            case 1: return "Income";
            case 4: return "Expenses";


            case 2:
            case 5:
                return "Amount";

            default:
                return super.getColumnName(column);
        }
    }

    @Override
    public int getRowCount() {
        if(inclomeList == null || expenseList == null) {
            if(inclomeList != null) {
                return inclomeList.size();
            }
            else if(expenseList != null) {
                return expenseList.size();
            }

            return 0;
        }

        return Math.max(inclomeList.size(), expenseList.size());
    }

    @Override
    public int getColumnCount() {
        return 6;
    }

    @Override
    public Object getValueAt(int row, int column) {
        Data inclome = null;
        Data expense = null;

        if(inclomeList != null && inclomeList.size() > row) {
            inclome = inclomeList.get(row);
        }

        if(expenseList != null && expenseList.size() > row) {
            expense = expenseList.get(row);
        }

        switch (column) {
            case 0: return inclome != null ? inclome.getDate() : "";
            case 1: return inclome != null ? inclome.getName() : "";
            case 2: return inclome != null ? inclome.getAmount() : "";
            case 3: return expense != null ? expense.getDate() : "";
            case 4: return expense != null ? expense.getName() : "";
            case 5: return expense != null ? expense.getAmount() : "";
        }

        return null;
    }

    public void update() {
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                Database database = new Database();
                inclomeList = database.getData(Database.TBL_INCOME);
                expenseList = database.getData(Database.TBL_EXPENSES);

                return null;
            }

            @Override
            protected void done() {
                try {
                    get();
                    fireTableDataChanged();
                }
                catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        };

        worker.execute();
    }
}

使用数据库的接口:

public class Database {
    public static final String TBL_INCOME = "tbl_income";
    public static final String TBL_EXPENSES = "tbl_expenses";

    private Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://192.168.40.5/test", "root", "");
    }

    public List<Data> getData(String tbl_name) throws SQLException {
        try (Connection connection = getConnection()) {
            String query = "select * from " + tbl_name;

            try(ResultSet rs = connection.createStatement().executeQuery(query)) {
                List<Data> list = new ArrayList<>();
                while (rs.next()) {
                    Data data = new Data();
                    data.setDate(rs.getDate("date"));
                    data.setName(rs.getString("particular"));
                    data.setAmount(rs.getDouble("amount"));

                    list.add(data);
                }

                return list;
            }
        }
    }
}

MainFrame.java

public class MainFrame extends JFrame {

    private JTable table = new JTable(new MyTableModel());

    public MainFrame() throws HeadlessException {
        super("MainFrame");
        createGUI();
    }

    private void createGUI() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(600, 400));

        JButton addI = new JButton("+");
        addI.addActionListener(e -> ((MyTableModel)table.getModel()).setIncomeData(new Data()));

        JButton addE = new JButton("+");
        addE.addActionListener(e -> ((MyTableModel)table.getModel()).setExpenseData(new Data()));

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
        panel.add(addI);
        panel.add(addE);

        JScrollPane scrollPane = new JScrollPane(table);
        add(scrollPane, BorderLayout.CENTER);
        add(panel, BorderLayout.PAGE_END);

        pack();
        setLocationRelativeTo(null);

        ((MyTableModel)table.getModel()).update();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
    }
}

【讨论】:

  • @mrmcwolf 你如何通过这种方法在 Jtable 中设置数据,我很困惑。
  • 看看我的帖子的编辑。
  • @mrmcwolf 抱歉,误读了代码
  • 谢谢@mrmcwolf 现在我需要在我的项目中尝试它真的有效。但这是一个漫长的过程......
  • @mrmcwolf 我如何在 DefaultTableModel 中设置数据
【解决方案2】:
+----+------------+----------------+--------+
| id | dateValue  |   particular   | amount |
+----+------------+----------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |      1 |
|  2 | 2017-02-03 | Cheque Deposit |      2 |
|  3 | 2017-02-08 | Cash Deposit   |      3 |
|  4 | 2017-02-07 | Product Sales  |      4 |
+----+------------+----------------+--------+

+----+------------+------------+--------+
| id | dateValue  | particular | amount |
+----+------------+------------+--------+
|  1 | 2017-05-07 | Factory    |      6 |
|  2 | 2017-06-02 | Staff      |      7 |
|  3 | 2017-06-03 | Travel     |      8 |
+----+------------+------------+--------+

然后我用select * from income left join expenses on income.id = expenses.id查询数据库得到:

+----+------------+----------------+--------+----+------------+------------+--------+--+
| id | dateValue  |   particular   | amount | id | dateValue  | particular | amount |  |
+----+------------+----------------+--------+----+------------+------------+--------+--+
|  1 | 2017-02-02 | Cash Deposit   |      1 |  1 | 2017-05-07 | Factory    |      6 |  |
|  2 | 2017-02-03 | Cheque Deposit |      2 |  2 | 2017-06-02 | Staff      |      7 |  |
|  3 | 2017-02-08 | Cash Deposit   |      3 |  3 | 2017-06-03 | Travel     |      8 |  |
|  4 | 2017-02-07 | Product Sales  |      4 |    |            |            |        |  |
+----+------------+----------------+--------+----+------------+------------+--------+--+

根据目前可用的信息,这可能是我能做的最好的了

您可以使用 Most simple code to populate JTable from ResultSetRetrieving Data from JDBC Database into Jtable 之类的东西来构建 JTable ... 作为可用示例

如果第二张表的行数比第一张表多.. 记录将不会显示第二张表中的 id 多的记录 – raman dangol 8 小时前

另外,如果 ID 不一致,记录将会丢失。这就是为什么我说这不是一个小问题

那么在这些情况下,像FULL OUTER JOIN 这样的东西会更有用。但是,根据我掌握的信息,MySQL 不支持full outer join,因为这很有用。然而,基于How to do a FULL OUTER JOIN in MySQL?,我们可以做类似...

select * from income left join expenses on income.id = expenses.id union select * from income right join expenses on income.id = expenses.id where income.id is null

它可以生成类似的东西

+----+------------+----------------+--------+----+------------+------------+--------+
| id | datevalue  |   particular   | amount | id | datevalue  | particular | amount |
+----+------------+----------------+--------+----+------------+------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |    1.0 |  1 | 2017-05-07 | Factory    |    6.0 |
|  2 | 2017-02-03 | Cheque Deposit |    2.0 |  2 | 2017-06-02 | Staff      |    7.0 |
|  3 | 2017-02-03 | Cash Deposit   |    3.0 |  3 | 2017-06-03 | Travel     |    8.0 |
|  4 | 2017-02-03 | Product Sales  |    4.0 |  4 | 2017-10-01 | Test 1     |   10.0 |
|  5 | 2017-10-02 | Test 2         |   20.0 |    |            |            |        |
+----+------------+----------------+--------+----+------------+------------+--------+

或者,如果您希望将事物与其“选定的面”保持一致,例如

select income.id, income.datevalue, income.PARTICULAR, income.AMOUNT, 
       expenses.id, expenses.datevalue, expenses.PARTICULAR, expenses.AMOUNT 
       from income join expenses on income.id = expenses.id
union all
select income.id, income.datevalue, income.PARTICULAR, income.AMOUNT, 
       null, null, null, null 
       from INCOME where not exists (select expenses.id from expenses where expenses.id = income.id)
union all
select null, null, null, null, 
       expenses.id, expenses.datevalue, expenses.PARTICULAR, expenses.AMOUNT 
       from expenses where not exists (select income.id from income where income.id = expenses.id)

这可以产生类似...的东西

+----+------------+----------------+--------+----+------------+------------+--------+
| id | datevalue  |   particular   | amount | id | datevalue  | particular | amount |
+----+------------+----------------+--------+----+------------+------------+--------+
|  1 | 2017-02-02 | Cash Deposit   |    1.0 |  1 | 2017-05-07 | Factory    |    6.0 |
|  2 | 2017-02-03 | Cheque Deposit |    2.0 |  2 | 2017-06-02 | Staff      |    7.0 |
|  3 | 2017-02-03 | Cash Deposit   |    3.0 |  3 | 2017-06-03 | Travel     |    8.0 |
|  4 | 2017-02-03 | Product Sales  |    4.0 |  4 | 2017-10-01 | Test 1     |   10.0 |
|    |            |                |        |  5 | 2017-10-02 | Test 2     |   20.0 |
+----+------------+----------------+--------+----+------------+------------+--------+

归根结底,这仍然是数据库问题。

为简单起见,您可以创建一个或多个数据库views 以简化查询

【讨论】:

  • 如果第二个表的行数比第一个表多..记录将不会显示第二个表中的id多
  • 另外,如果ID不一致,记录会丢失。这就是为什么我说这不是一个小问题。
  • 然后我有收入表和费用表有日期,特别,金额如何在 jtable 中显示
  • @mrmcwolf 没关系
  • @mrmcwolf 然后你看像full outer join
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-13
  • 2012-09-13
  • 1970-01-01
相关资源
最近更新 更多