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

发布于 2024-08-19 18:58:25 字数 147 浏览 6 评论 0原文

我想显示一个 JTable,它按原样显示数据库表中的数据。

到目前为止,我已经使用 JTable 显示来自 Object [ ] [ ] 的数据。

我知道显示数据的一种方法是首先将数据库表转换为对象[][],但是有没有其他简单但更强大和灵活的方法。

I want to display a JTable that display the data from a DataBase table as it is.

Up till now, I have used JTable that displays data from Object [ ][ ].

I know one way to display the data is to first convert the database table into Object [ ][ ] but Is there any other which is easy yet more powerful and flexible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

茶底世界 2024-08-26 18:58:25

我建议采用以下方法:

  • 创建一个 Row 类来表示从 ResultSet 读取的行。这可以是 Object[] 的简单包装。
  • 创建一个 List 集合,以及由该集合支持的子类 AbstractTableModel
  • 使用 SwingWorker 通过从后台线程(即在 doInBackground() 方法中)。调用 SwingWorkerpublish 方法将 Row 发布回事件调度线程(例如每 100 行)。
  • 当使用读取的最新行块调用 SwingWorkerprocess 方法时,将它们添加到 List 并触发适当的 < code>TableEvents 导致显示更新。
  • 另外,使用 ResultSetMetaData 确定 TableModel 定义中每列的 Class。这将使它们正确渲染(如果您仅使用 2D Object[][] 数组,则不会出现这种情况)。

这种方法的优点是,在处理大型 ResultSet 时,UI 不会锁定,并且显示会随着结果的处理而逐渐更新。

编辑

添加了以下示例代码:

/**
 * 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();

I would recommend taking the following approach:

  • Create a Row class to represent a row read from your ResultSet. This could be a simple wrapper around an Object[].
  • Create a List<Row> collection, and subclass AbstractTableModel to be backed by this collection.
  • Use a SwingWorker to populate your List<Row> by reading from the underlying ResultSet on a background thread (i.e. within the doInBackground() method). Call SwingWorker's publish method to publish Rows back to the Event Dispatch thread (e.g. every 100 rows).
  • When the SwingWorker's process method is called with the latest chunk of Rows read, add them to your List<Row> and fire appropriate TableEvents to cause the display to update.
  • Also, use the ResultSetMetaData to determine the Class of each column within the TableModel definition. This will cause them to be rendered correctly (which won't be the case if you simply use a 2D Object[][] array).

The advantage of this approach is that the UI will not lock up when processing large ResultSets, and that the display will update incrementally as results are processed.

EDIT

Added example code below:

/**
 * 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();
等数载,海棠开 2024-08-26 18:58:25

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

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

这本由 George Reese 编写的给出了其类RowSetModel的源代码,以适应RowSet 作为 TableModel。开箱即用地为我工作。我唯一的改变是为该类起了一个更好的名称:RowSetTableModel

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

CachedRowSet 实现会为您完成这项工作,而不是像本页其他答案中所讨论的那样创建 Row 类、Row 对象列表和 ResultSetMetaData。

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

行集教程

Another powerful and flexible way to display database data in a JTable is to load your query's resulting data into a CachedRowSet, then connect it to the JTable with TableModel adapter.

  1. Query ---> Database data ---> RowSet
  2. RowSet <--> TableModel adapter <--> JTable

This book by George Reese gives the source code for his class RowSetModel to adapt a RowSet as a TableModel. Worked for me out-of-the-box. My only change was a better name for the class: RowSetTableModel.

A RowSet is a subinterface of ResultSet, added in Java 1.4. So a RowSet is a ResultSet.

A CachedRowSet implementation does the work for you, instead of you creating a Row class, a List of Row objects, and ResultSetMetaData as discussed in other answers on this page.

Sun/Oracle provides a reference implementation of CachedRowSet. Other vendors or JDBC drivers may provide implementations as well.

RowSet tutorial

有深☉意 2024-08-26 18:58:25

根据您已经完成的操作以及您愿意执行的操作,我一直在使用 Netbeans 及其对数据库驱动应用程序的 Beans 绑定支持,非常成功。您将 JTable 绑定到数据库,它会自动构建 JPA 查询。

Depending on what you've done already and what you're willing to do, I've been using Netbeans with its Beans Binding support for a database-driven app very successfully. You bind your JTable to a database and it automatically builds the JPA queries.

带刺的爱情 2024-08-26 18:58:25

使用 ResultSet 填充 jTable 的最佳方法

先决条件

1) 结果集“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);
        }

Best way to fill jTable with ResultSet

Prerequisites

1) Result Set "rs" is populated with data you need.
2) JTable "jTable1" is created before hand
3) Table Header is implemented before hand

Implementation

        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);
        }
昨迟人 2024-08-26 18:58:25

您必须在那里创建一个自定义 TableModel您可以指定数据的来源和方式。

您确实必须首先完全理解 JTable + TableModel 工作,然后请遵循之前发布的答案之一。

You have to create a custom TableModel There you can specify where and how the data is coming from.

You really have to fully understand first how JTable + TableModel works and then follow one of the previously posted answers.

热血少△年 2024-08-26 18:58:25

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

I know the question is old but for anyone following Adamski's solution, care should be taken while sharing the ResultSet and ResultSetMetadata between gui and SwingWorker threads. I got an inconsistent internal state exception while using this approach with SQLite. The solution is to load any metadata to private fields before executing the SwingWorker and have the getter functions (getColumnName etc.) to return the fields instead.

┈┾☆殇 2024-08-26 18:58:25

我给出了一个在 JTable 中显示数据库表数据的小方法。您只需传递数据库表的结果集作为参数。


    // 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;

//First set the Table header for(i = 0; i < count; i++) { model.addColumn(header[i]); } jt.setModel(model); //Represents table Model jf.add(jt.getTableHeader(),BorderLayout.NORTH); a = new String[count]; // Adding Database table Data in the JTable try { while (rs.next()) { for(i = 0; i < count; i++) { a[i] = rs.getString(i+1); } model.addRow(a); //Adding the row in table model jt.setModel(model); // set the model in jtable } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Exception : "+e, "Error", JOptionPane.ERROR_MESSAGE); } }

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;

//First set the Table header for(i = 0; i < count; i++) { model.addColumn(header[i]); } jt.setModel(model); //Represents table Model jf.add(jt.getTableHeader(),BorderLayout.NORTH); a = new String[count]; // Adding Database table Data in the JTable try { while (rs.next()) { for(i = 0; i < count; i++) { a[i] = rs.getString(i+1); } model.addRow(a); //Adding the row in table model jt.setModel(model); // set the model in jtable } } catch (Exception e) { JOptionPane.showMessageDialog(null, "Exception : "+e, "Error", JOptionPane.ERROR_MESSAGE); } }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文