JDBC TableModel для JTable в Java? - PullRequest
       16

JDBC TableModel для JTable в Java?

2 голосов
/ 04 февраля 2010

Я хочу отобразить таблицу базы данных в виде JTable. Я никогда раньше не использовал JTable, поэтому я погуглил 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. Пользователь может редактировать таблицу напрямую, и когда он нажимает кнопку «Сохранить», изменения отражаются в данных базы данных
  3. Пользователь может вставлять данные напрямую.
  4. Пользователь может удалять данные напрямую.

1 Ответ

1 голос
/ 05 февраля 2010

Я предполагаю, что вы реализовали 1 в соответствии с тем, что Адамски предложил в вашем предыдущем вопросе. Также, как предлагает Саной, перейдите на использование какого-либо списка для хранения ваших данных.

  1. Для поддержки 2-4 вы должны убедиться, что данные, которые вы извлекаете из базы данных, поступают только из одной таблицы и не содержат никаких производных данных (например, агрегаты, столбец 1 + столбец 2). Вам нужно будет отслеживать ваше предложение where, если вы хотите разрешить пользователю фильтровать строки.

  2. В каждой строке сохраните другую строку (назовем ее updatedRow), которая представляет обновления, которые пользователь сделал с помощью графического интерфейса. После того, как в строку внесено какое-либо обновление, это поле должно быть заполнено новой строкой, содержащей обновленные данные. Когда нажата кнопка «Сохранить», вы запускаете запросы на обновление для всех строк с ненулевым updatedRow, обновляя базу данных данными в updatedRow, которые не совпадают с данными из исходной строки (не обновляйте, если пользователь изменяет данные обратно на это было изначально). У вас также может быть другая кнопка «Отменить обновления», которая заполняет таблицу исходными данными для всех строк с ненулевым updatedRow.

    Я настоятельно рекомендую вам хранить дополнительные метаданные, для которых поля образуют первичный ключ, и не допускать их изменения, поскольку обновления таких столбцов могут быть дорогостоящими (поскольку они предположительно проиндексированы и могут иметь некоторые ограничения RI). Это следует отразить в графическом интерфейсе, сделав такие столбцы недоступными для редактирования. Предложение where в обновлениях будет использовать только эти поля, а не все поля (вам все равно понадобятся другие фильтры, которые ваш пользователь установил в 1).

  3. Я бы предложил двухэтапный процесс. Пользователь начинает с нажатия кнопки, которая добавляет строку в таблицу. После ввода данных пользователь нажимает другую кнопку для вставки в базу данных (или вы можете объединить эту функцию с обновлениями в кнопке «Сохранить»). Вам необходимо разрешить редактирование полей первичного ключа для вновь вставленных строк, если столбцы первичного ключа не являются автоматически сгенерированным идентификатором.

    В отличие от того, какие строки уже есть в базе данных, а какие нет, я бы предложил сохранить список вновь вставленных строк.

    Если вы разрешите пользователю выбирать только определенные столбцы для отображения в таблице, вам нужно будет определить, как обращаться с не отображаемыми столбцами (например, разрешить базе данных установить значение по умолчанию, заполнить автоматически сгенерированным идентификатором).

  4. Вероятно, лучше всего реализовать это, имея флажок с каждой строкой, затем, когда нажимается кнопка «Удалить», он вызывает SQL для удаления каждой проверенной строки с использованием фильтра из 1 и метаданных первичного ключа, упомянутых в 2, а также убрать его со стола.

Общие соображения:

  • Один и тот же метод setValueAt будет использоваться как для обновленных, так и для вставленных строк, но вам нужно другое поведение. Вы хотите установить updatedRow для обновлений, но не при редактировании строк, которые собираетесь вставить.

  • Как вы будете обрабатывать ошибки, такие как несоблюдение ограничений или неправильный ввод (например, 'abcde' в числовом поле)?

  • SQL-инъекция.

...