java - Java 中 JTable 的 JDBC TableModel?

标签 java swing jdbc jtable 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 具有以下功能:

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

最佳答案

我假设您已经根据 Adamski 在上一个问题中的建议实现了 1。此外,正如 Sanoj 所建议的那样,更改为使用某种列表来存储您的数据。

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

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

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

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

    为了区分哪些行已经在数据库中,哪些不在数据库中,我建议存储一个新插入行的列表。

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

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

一般注意事项:

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

  • 您将如何处理错误,例如不满足约束或输入无效(例如,数字字段中的“abcde”)?

  • SQL 注入(inject)。

关于java - Java 中 JTable 的 JDBC TableModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2201886/

相关文章:

Java 查找我单击的图像?

java - 尽管我生成的查询工作正常,但为什么 JDBC-MySQL 会在 SQL 语法中抛出错误?

java - 为什么 mysql JDBC 驱动程序返回 TRANSACTION_READ_COMMITTED 作为默认隔离级别

java - AWS DynamoDB 的 Eclipse Spring Boot 问题

java - 如何对重复的对象列表进行排序

java - 如何在不加载额外代码的情况下在 ArrayList 中实现 Strings 和 SpannableStrings 的混合

java - 单击后禁用 JButton 并在完成工作后启用

java - 基于时区计算时间

java - 为什么我的纹理不起作用?

java - 数据库中的编码问题