Как заполнить данные в JTable с помощью базы данных?
Я хочу отобразить JTable, который отображает данные из таблицы DataBase, как есть.
До сих пор я использовал JTable, который отображает данные из Object [] [].
Я знаю, что один способ отображения данных - сначала преобразовать таблицу базы данных в Object [] [], но есть ли другие, которые являются легкими, но более мощными и гибкими.
Ответы
Ответ 1
Я бы рекомендовал использовать следующий подход:
- Создайте класс
Row
для представления строки, считанной с вашего ResultSet
. Это может быть простая оболочка вокруг Object[]
.
- Создайте коллекцию
List<Row>
и подкласс AbstractTableModel
для поддержки этой коллекции.
- Используйте
SwingWorker
для заполнения вашего List<Row>
путем чтения из базового ResultSet
в фоновом потоке (т.е. в методе doInBackground()
). Вызовите SwingWorker
publish
метод для публикации Row
обратно в поток Dispatch Event (например, каждые 100 строк).
- Когда вызывается метод
SwingWorker
process
с последним фрагментом чтения строк, добавьте их в свой List<Row>
и выполните пожар соответствующего TableEvent
, чтобы заставить дисплей обновляться.
- Также используйте
ResultSetMetaData
для определения Class
каждого столбца в определении TableModel
. Это приведет к их правильной визуализации (это не произойдет, если вы просто используете массив 2D Object[][]
).
Преимущество такого подхода заключается в том, что пользовательский интерфейс не будет блокироваться при обработке больших ResultSet
s и что дисплей будет обновляться постепенно по мере обработки результатов.
ИЗМЕНИТЬ
Добавлен пример кода ниже:
/**
* 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();
Ответ 2
Другим мощным и гибким способом отображения данных базы данных в JTable является загрузка ваших полученных данных запроса в CachedRowSet, затем подключите его к JTable с адаптером TableModel.
- Запрос --- > Данные базы данных --- > RowSet
- RowSet ↔ Адаптер TableModel ↔ JTable
Эта книга Джорджа Риз дает исходный код для класса RowSetModel для адаптации RowSet в качестве TableModel. Работал для меня из коробки. Мое единственное изменение было лучшим именем для класса: RowSetTableModel.
A RowSet - это субинтерфейс ResultSet, добавленный в Java 1.4. Итак, RowSet - это ResultSet.
Реализация CachedRowSet выполняет вашу работу, вместо того, чтобы создавать класс Row, объекты List of Row и ResultSetMetaData, как описано в других ответах на этой странице.
Sun/Oracle предоставляет ссылочную реализацию CachedRowSet. Другие производители или драйверы JDBC могут также обеспечивать реализацию.
Учебное пособие по RowSet
Ответ 3
В зависимости от того, что вы уже сделали и чего хотите, я очень успешно использовал Netbeans с поддержкой Beans Binding для приложения, управляемого базой данных. Вы связываете JTable с базой данных и автоматически создаете запросы JPA.
Ответ 4
Лучший способ заполнить jTable с помощью ResultSet
Необходимые условия
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 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);
}
Ответ 5
Вам нужно создать пользовательский TableModel Там вы можете указать, откуда и как поступают данные.
Вам действительно нужно полностью понять, как JTable + TableModel, а затем следуйте одному из ранее опубликованных ответов.
Ответ 6
Я знаю, что вопрос старый, но для любого, кто следует за решением Adamski, следует соблюдать осторожность при обмене потоками ResultSet
и ResultSetMetadata
между потоками gui и SwingWorker
. При использовании этого подхода с SQLite я получил несогласованное внутреннее исключение. Решение состоит в том, чтобы загружать любые метаданные в частные поля перед выполнением SwingWorker
и иметь функции getter (getColumnName и т.д.), Чтобы вместо этого возвращать поля.
Ответ 7
Я даю небольшой метод для отображения данных таблицы базы данных в 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);
}
}