IMHO roten till den dåliga beständigheten är att du i onödan frågar databasen flera gånger för att få informationen (kolumner, rader, radnummer, kolumnnummer, etc) du behöver:
För att få kolumnnummer:
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
För att få radnummer:
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
För att få rader (det här är det värsta eftersom det är inuti en slinga):
data = stmt.executeQuery("SELECT " + columnName + " FROM " + tableName + " LIMIT " + j + ", " + 1);
Hur man löser det
Fråga bara databasen en gång. En enda Resultatuppsättning
och dess associerade ResultSetMetaData
borde vara tillräckligt för att uppnå ditt mål. Dessutom, och som redan föreslagits, använd en SwingWorker
att göra databasanrop i en separat tråd. Till exempel:
final JTable table = new JTable();
SwingWorker<Void, TableModel> worker = new SwingWorker<Void, TableModel> () {
@Override
protected Void doInBackground() throws Exception {
ResultSet resultSet = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount(); // columns number
String[] columnNames = new String[columnCount];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = metaData.getColumnName(i); // fill columns names
}
resultSet.last();
int rowCount = resultSet.getRow(); // get rows number
resultSet.beforeFirst();
Object[][] data = new Object[rowCount][columnCount];
int currentRow = 0;
while (resultSet.next()) {
for (int currentColumn = 1; currentColumn <= columnCount; currentColumn++) {
data[currentRow][currentColumn - 1] = resultSet.getObject(currentColumn); // fill data set
}
currentRow++;
}
TableModel model = new DefaultTableModel(data, columnNames);
publish(model);
return null;
}
@Override
protected void process(List<TableModel> chunks) {
TableModel model = chunks.get(0);
table.setModel(model);
}
}
worker.execute();