如何使用数据库填充JTable中的数据?

19

我想要展示一个JTable,它可以直接展示来自数据库表的数据。

迄今为止,我使用的是从Object[][]展示数据的JTable。

我知道一种方法是先将数据库表转换为Object[][],但是否还有其他更易用、更强大和灵活的方式呢?

7个回答

25
我建议采取以下方法:
  • 创建一个Row类来表示从ResultSet中读取的一行。这可以是一个简单的Object[]包装器。
  • 创建一个List<Row>集合,并子类化AbstractTableModel以由此集合支持。
  • 使用SwingWorker后台线程(即在doInBackground()方法内)中从底层ResultSet中读取以填充List<Row>。调用SwingWorkerpublish方法将Row发布回事件分派线程(例如每100行)。
  • 当调用SwingWorkerprocess方法并读取最新的一块Row时,将它们添加到List<Row>中,并触发适当的TableEvent以导致显示更新。
  • 此外,使用ResultSetMetaData来确定TableModel定义中每列的Class。这将使它们正确呈现(如果仅使用2D Object[][]数组,则不会出现这种情况)。

这种方法的优点是在处理大型ResultSet时,用户界面不会锁定,并且随着结果的处理,显示将逐步更新。

编辑

下面是示例代码:

/**
 * Simple wrapper around Object[] representing a row from the ResultSet.
 */
private class Row {
  private final Object[] values;

  public Row(Object[] values) {
    this.values = values;
  }

  public int getSize() {
    return values.length;
  }

  public Object getValue(int i) {
    return values[i];
  }
}

// TableModel implementation that will be populated by SwingWorker.
public class ResultSetTableModel extends AbstractTableModel {
  private final ResultSetMetaData rsmd;
  private final List<Row> rows;

  public ResultSetTableModel(ResultSetMetaData rsmd) {
    this.rsmd = rsmd;
    this.rows = new ArrayList<Row>();
  }

  public int getRowCount() {
    return rows.size();
  }

  public int getColumnCount() {
    return rsmd.getColumnCount();
  }

  public Object getValue(int row, int column) {
    return rows.get(row).getValue(column);
  }

  public String getColumnName(int col) {
    return rsmd.getColumnName(col - 1); // ResultSetMetaData columns indexed from 1, not 0.
  }

  public Class<?> getColumnClass(int col) {
    // TODO: Convert SQL type (int) returned by ResultSetMetaData.getType(col) to Java Class.
  }
}

// SwingWorker implementation
new SwingWorker<Void, Row>() {
  public Void doInBackground() {
    // TODO: Process ResultSet and create Rows.  Call publish() for every N rows created.
  }

  protected void process(Row... chunks) {
    // TODO: Add to ResultSetTableModel List and fire TableEvent.
  }
}.execute();

1
我已经收到你的回答,但是脑海中仍有一些疑惑。请使用一小段代码片段进行具体说明。 - Amit
我已经在我的新问题中作为评论提到了我的问题。 - Amit

7

在JTable中展示数据库数据的另一种强大而灵活的方式是将查询结果数据加载到CachedRowSet中,然后使用TableModel适配器将其连接到JTable

  1. 查询 ---> 数据库数据 ---> RowSet
  2. RowSet <--> TableModel适配器 <--> JTable

这本由George Reese编写的书籍提供了源代码,用于将RowSet适配为TableModel的RowSetModel类。对我来说,开箱即用。我的唯一更改是更好的类名:RowSetTableModel

RowSet是ResultSet的子接口,Java 1.4中添加。因此,RowSet 就是 ResultSet。

CachedRowSet实现可以为您完成工作,而无需像本页其他答案中讨论的那样创建Row类、Row对象列表和ResultSetMetaData。

Sun/Oracle提供了CachedRowSet的参考实现。其他供应商或JDBC驱动程序也可能提供实现。 RowSet教程

4

使用ResultSet填充jTable的最佳方法

前提条件

1)Result Set“rs”已经包含了您需要的数据。 2)在预先创建JTable“jTable1”。 3)表头已经预先实现。

实现步骤

        java.sql.ResultSet rs = datacn.executeSelectQuery(query);
        //Filling JTable with Result set

        // Removing Previous Data
        while (jTable1.getRowCount() > 0) {
            ((DefaultTableModel) jTable1.getModel()).removeRow(0);
        }

        //Creating Object []rowData for jTable's Table Model        
        int columns = rs.getMetaData().getColumnCount();
        while (rs.next())
        {  
            Object[] row = new Object[columns];
            for (int i = 1; i <= columns; i++)
            {  
                row[i - 1] = rs.getObject(i); // 1
            }
            ((DefaultTableModel) jTable1.getModel()).insertRow(rs.getRow() - 1,row);
        }

4

根据您已经完成的工作和愿意做的事情,我一直非常成功地使用Netbeans及其Beans Binding支持来开发数据库驱动的应用程序。您可以将JTable绑定到数据库,它会自动构建JPA查询。


3
你需要创建一个自定义的 TableModel,在那里你可以指定数据来自何处以及如何获取。
你真的需要完全理解 JTable + TableModel 的工作原理,然后按照先前发布的答案之一进行操作。

1
我知道这个问题很老了,但是对于跟随Adamski解决方案的人来说,在GUI和SwingWorker线程之间共享ResultSet和ResultSetMetadata时应该要小心。我在使用SQLite时使用这种方法时遇到了不一致的内部状态异常。解决方案是在执行SwingWorker之前将任何元数据加载到私有字段中,并使getter函数(getColumnName等)返回这些字段。

0

I am giving a small method for display database table data in JTable. You need to pass only the resultset of the database table as parameter.


    // rs is the ResultSet of the Database table
    public void displayData(ResultSet rs)
    {
        //jt Represents JTable
        //jf represents JFrame
        int i;
        int count;
        String a[];
        String header[] = {"1","2","3","4","5"};   //Table Header Values, change, as your wish
        count = header.length;

//首先设置表头 for(i = 0; i < count; i++) { model.addColumn(header[i]); } jt.setModel(model); //表示表格模型 jf.add(jt.getTableHeader(),BorderLayout.NORTH);
a = new String[count];
//将数据库表数据添加到JTable中 try { while (rs.next()) { for(i = 0; i < count; i++) { a[i] = rs.getString(i+1); } model.addRow(a); //将行添加到表格模型中 jt.setModel(model); //在jtable中设置模型 } }
catch (Exception e) { JOptionPane.showMessageDialog(null, "异常:"+e, "错误", JOptionPane.ERROR_MESSAGE); }

我知道这个回答有些老了,但是“model”是什么意思呢? - Raptrex
模型是TableModel对象。 - Ram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接