Java中JTable的JDBC TableModel?

我想将数据库表显示为JTable。 我之前从未使用过JTable,所以我用Google搜索了JTable和TableModel。

通过谷歌搜索,我能够编写自己的自定义TableModel,显示存储的数据

Object[][] data; 

现在,我想将我的数据库表数据显示到JTable中。 我也搜索了一下并且已经了解了这一点,但仍然对在AbstractTableModel的实现类中应该去哪里感到困惑。

以下是自定义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("--------------------------"); } } 

现在,如何更改上面的代码,以便我的JTable可以具有以下function:

  1. 它显示数据库中的数据
  2. 用户可以直接编辑表格,当他点击“保存”按钮时,更改会反映在数据库数据中
  3. 用户可以直接插入数据。
  4. 用户可以直接删除数据。

根据Adamski在您之前的问题中提出的建议,我假设您已经实施了1。 此外,正如Sanoj所建议的那样,更改为使用某种List来存储数据。

  1. 要支持2-4,您必须确保从数据库中提取的数据仅来自一个表,并且不涉及派生数据(例如,聚合,column1 + column2)。 如果您打算让用户过滤行,则需要跟踪where子句。

  2. 在每一行中,存储另一行(我们称之为updatedRow),表示用户使用GUI进行的更新。 对行进行任何更新后,需要使用包含更新数据的新Row填充此字段。 单击“保存”时,对所有具有非null updatedRow的行运行更新查询,使用updatedRow中的数据更新数据库,该数据与原始行中的数据不匹配(如果用户将数据更改回如何更新,请不要更新它原来是)。 您可能还有另一个“撤消更新”按钮,该按钮使用非null updatedRow的所有行的原始数据填充表。

    我强烈建议您存储关于哪些字段构成主键的其他元数据,并防止这些字段被更改,因为对这些列的更新可能很昂贵(因为它们可能被索引并且可能附加了一些RI约束)。 这应该通过使这些列不可编辑而反映在GUI中。 更新中的where子句将仅使用这些字段而不是所有字段(您仍然需要用户在1中设置的其他filter)。

  3. 我建议分两个步骤。 用户首先单击向表中添加行的按钮。 输入数据后,用户单击另一个按钮以插入数据库(或者您可以将此function与“保存”按钮中的更新结合使用)。 如果主键列不是某些自动生成的ID,则需要允许主键字段对新插入的行进行编辑。

    对于哪些行已经存在于数据库中以及哪些不存在,我建议存储新插入的行列表。

    如果让用户只选择要在表中显示的某些列,则需要确定如何处理未显示的列(例如,让数据库设置为默认值,使用自动生成的ID填充)。

  4. 可能最好通过在每行上设置一个复选框来实现这一点,然后在单击“删除”按钮时,它会调用SQL以使用1中的filter和2中提到的主键元数据删除每个选中的行,并将其删除从表中。

一般考虑:

  • 相同的setValueAt方法将用于更新和插入的行,但您需要不同的行为。 您希望为更新设置updatedRow,但在编辑要插入的行时不会。

  • 您将如何处理诸如未满足约束或无效输入之类的错误(例如,数字字段中的’abcde’)?

  • SQL注入。