简体   繁体   English

Java中的JTable的JDBC TableModel?

[英]JDBC TableModel for a JTable in Java?

I want to display a database table as a JTable. 我想将数据库表显示为JTable。 I have never used JTable before so I googled JTable and TableModel. 我以前从未使用过JTable,所以我在JTable和TableModel上进行了谷歌搜索。

With that googling, I am able to write my own custom TableModel which show data stored in 通过谷歌搜索,我可以编写自己的自定义TableModel来显示存储在

Object[][] data;

Now, I want to show my database table data into JTable. 现在,我想将数据库表数据显示到JTable中。 I searched that also and have got an idea of that but still confused about what should goes where in the implementation class of AbstractTableModel. 我也进行了搜索,虽然对此有所了解,但对于在AbstractTableModel的实现类中应该去哪里仍然感到困惑。

Following is the code of custom TableModel. 以下是自定义TableModel的代码。

public abstract class AbstractPOLDATTableModel extends AbstractTableModel {
protected boolean DEBUG = false;
private String[] columnNames;
private Object[][] data;

protected AbstractPOLDATTableModel(String[] columnNames, Object[][] data) {
    this.columnNames = columnNames;
    this.data = data;
}

public int getColumnCount() {
    return columnNames.length;
}

public int getRowCount() {
    return data.length;
}

@Override
public String getColumnName(int col) {
    return columnNames[col];
}

public Object getValueAt(int row, int col) {
    return data[row][col];
}

@Override
public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
}

@Override
public boolean isCellEditable(int row, int col) {
    if (col < 2) {
        return false;
    } else {
        return true;
    }
}

@Override
public void setValueAt(Object value, int row, int col) {
    if (DEBUG) {
        System.out.println("Setting value at " + row + "," + col
                           + " to " + value
                           + " (an instance of "
                           + value.getClass() + ")");
    }

    data[row][col] = value;
    fireTableCellUpdated(row, col);

    if (DEBUG) {
        System.out.println("New value of data:");
        printDebugData();
    }
}

private void printDebugData() {
    int numRows = getRowCount();
    int numCols = getColumnCount();

    for (int i=0; i < numRows; i++) {
        System.out.print("    row " + i + ":");
        for (int j=0; j < numCols; j++) {
            System.out.print("  " + data[i][j]);
        }
        System.out.println();
    }
    System.out.println("--------------------------");
}
}

Now, how to change the above code so that my JTable can have the follwing features: 现在,如何更改上面的代码,以便我的JTable可以具有以下功能:

  1. It shows data from the database 它显示了来自数据库的数据
  2. User can edit the table directly and when he clicks on a "save" button, the changes reflect in the database data 用户可以直接编辑表,当他单击“保存”按钮时,更改将反映在数据库数据中
  3. User can insert data directly. 用户可以直接插入数据。
  4. User can delete data directly. 用户可以直接删除数据。

I'm assuming you've implemented 1 according to what Adamski suggested in your previous question. 我假设您已经根据Adamski在上一个问题中提出的建议实施了1。 Also, as suggested by Sanoj, change to using some sort of List to store your data. 同样,如Sanoj所建议,更改为使用某种列表来存储数据。

  1. To support 2-4, you must ensure that the data you're pulling out of the database comes from only one table and involves no derived data (eg. aggregations, column1 + column2). 要支持2-4,必须确保从数据库中提取的数据仅来自一个表,并且不包含任何派生数据(例如,聚合,column1 + column2)。 You will need to keep track of your where clause, if you intend to let the user filter rows. 如果要让用户筛选行,则需要跟踪where子句。

  2. Within each Row, store another Row (let's call it updatedRow) that represents the updates the user has made using the GUI. 在每一行中,存储代表用户使用GUI进行的更新的另一行(我们将其称为updatedRow)。 Once any update is made to the row, this field needs to be populated with a new Row containing the updated data . 一旦对该行进行了任何更新,就需要用包含更新数据的新行填充该字段。 When "Save" is clicked, you run update queries for all Rows with a non-null updatedRow, updating the database with data in updatedRow which do not match those from the original Row (don't update if the user changes data back to how it was originally). 单击“保存”后,您将使用非null的updatedRow对所有行运行更新查询,并使用updatedRow中的数据与原始行中的数据不匹配来更新数据库(如果用户将数据更改回原来的方式,则不要更新原来是)。 You might also have another "Undo Updates" button which populates the table with the original data for all Rows with a non-null updatedRow. 您可能还具有另一个“撤消更新”按钮,该按钮将使用具有非null UpdatedRow的所有行的原始数据填充表。

    I would strongly recommend that you store additional metadata on which fields form the primary key and prevent those from being changed, as updates to such columns may be expensive (since they are presumably indexed and may have some RI constraints attached). 我强烈建议您存储额外的元数据,在这些元数据上构成主键的字段并防止其被更改,因为对此类列的更新可能会很昂贵(因为它们可能已被索引并且可能附加了一些RI约束)。 This should be reflected in the GUI by making such columns not editable. 应该通过使此类列不可编辑来在GUI中反映出来。 The where clause in updates would use only these fields rather than all fields (you will still need other filters that your user set in 1). 更新中的where子句将仅使用这些字段,而不使用所有字段(您仍然需要用户在1中设置的其他过滤器)。

  3. I'd suggest a two step process. 我建议分两个步骤进行。 The user starts by clicking a button which adds a row to the table. 用户通过单击向表添加一行的按钮开始。 After entering data, the user clicks another button to insert into the database (or you can combine this functionality with updates in the "save" button). 输入数据后,用户单击另一个按钮以插入数据库中(或者您可以将此功能与“保存”按钮中的更新结合在一起)。 You will need to allow primary key fields to be editable for newly inserted rows if the primary key columns aren't some auto-generated ID. 如果主键列不是某些自动生成的ID,则需要允许新插入的行的主键字段可编辑。

    To different between which Rows are already in the database and which ones aren't, I'd suggest storing a list of newly inserted Rows. 为了区分数据库中已有哪些行和哪些行没有,我建议存储一个新插入的行的列表。

    If you let the user pick only certain columns to display in the table, you will need to determine how to deal with the columns that aren't being displayed (eg. let the database set a default, populate with auto-generated ID). 如果让用户仅选择要在表中显示的某些列,则需要确定如何处理未显示的列(例如,让数据库设置默认值,并使用自动生成的ID进行填充)。

  4. Probably best to implement this by having a checkbox with each Row, then when the "Delete" button is clicked, it calls SQL to delete each checked Row using the filter from 1 and primary key metadata mentioned in 2, as well as to remove it from the table. 最好通过在每个行上都有一个复选框来实现此目的,然后单击“删除”按钮,它将调用SQL以使用1中的过滤器和2中提到的主键元数据删除每个选中的行,然后将其删除从桌子上。

General considerations: 一般注意事项:

  • The same setValueAt method will be used for both updated and inserted Rows, but you want different behaviour. 相同的setValueAt方法将用于更新的行和插入的行,但是您需要不同的行为。 You want to set updatedRow for updates, but not when editting Rows you're about to insert. 您想为更新设置“ updatedRow”,而不是在编辑要插入的行时设置。

  • How will you handle errors such as constraints not being met or invalid input (eg. 'abcde' in a numeric field)? 您将如何处理错误,例如无法满足约束或输入无效(例如,数字字段中的“ abcde”)?

  • SQL injection. SQL注入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM