sql >> Base de Datos >  >> RDS >> Mysql

Optimice las llamadas de datos en JDBC en JTable

En mi humilde opinión, la raíz del mal rendimiento es que consulta la base de datos varias veces innecesariamente para obtener los datos (columnas, filas, número de filas, número de columnas, etc.) que necesita:

Para obtener el número de columnas:

ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);

Para obtener el número de filas:

ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);

Para obtener filas (este es el peor porque está dentro de un bucle):

data = stmt.executeQuery("SELECT " + columnName + " FROM " + tableName + " LIMIT " + j + ", " + 1);

Cómo resolverlo

Solo consulta la base de datos una vez. Un único ResultSet y su asociado ResultSetMetaData debería ser suficiente para lograr su objetivo. Además, y como ya se sugirió, use un SwingWorker para hacer llamadas a la base de datos en un hilo separado. Por ejemplo:

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();