¿Cómo llenar los datos en una JTable con base de datos?

Quiero mostrar una JTable que muestre los datos de una tabla de DataBase tal como está.

Hasta ahora, he usado JTable que muestra datos de Object [] [].

Sé que una forma de mostrar los datos es convertir primero la tabla de la base de datos en Objeto [] [], pero ¿Existe alguna otra que sea más fácil pero más poderosa y flexible?

Yo recomendaría tomar el siguiente enfoque:

  • Cree una clase de Row para representar una lectura de fila de su ResultSet . Esto podría ser un simple contenedor alrededor de un Object[] .
  • Cree una colección de List y la subclase AbstractTableModel para que esta colección la respalde.
  • Utilice un SwingWorker para completar su List leyendo el ResultSet subyacente en una doInBackground() fondo (es decir, dentro del método doInBackground() ). Llame al método de publicación de SwingWorker para volver a publicar Row en el hilo Despacho de evento (por ejemplo, cada 100 filas).
  • Cuando se llama al método de process SwingWorker con la última porción de filas leída, agréguelas a su List y TableEvent los TableEvent apropiados para hacer que la pantalla se actualice.
  • Además, use ResultSetMetaData para determinar la Class de cada columna dentro de la definición de TableModel . Esto hará que se rendericen correctamente (lo que no será el caso si simplemente usas una matriz 2D Object[][] ).

La ventaja de este enfoque es que la UI no se bloqueará cuando se procesen ResultSet s grandes y que la pantalla se actualizará gradualmente a medida que se procesen los resultados.

EDITAR

Se agregó un código de ejemplo a continuación:

 /** * 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 rows; public ResultSetTableModel(ResultSetMetaData rsmd) { this.rsmd = rsmd; this.rows = new ArrayList(); } 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() { 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(); 

Otra forma poderosa y flexible de mostrar los datos de la base de datos en una JTable es cargar los datos resultantes de su consulta en un CachedRowSet , luego conectarlo a JTable con el adaptador TableModel .

  1. Consulta —> Datos de la base de datos —> RowSet
  2. RowSet <-> adaptador TableModel <-> JTable

Este libro de George Reese da el código fuente de su clase RowSetModel para adaptar un RowSet como un TableModel. Funcionó para mí desde el primer momento. Mi único cambio fue un mejor nombre para la clase: RowSetTableModel .

Un RowSet es una subinterfaz de ResultSet, agregado en Java 1.4. Entonces un RowSet es un ResultSet.

Una implementación de CachedRowSet hace el trabajo por usted, en lugar de crear una clase de Fila, una Lista de objetos de Fila y ResultSetMetaData como se explica en otras respuestas en esta página.

Sun / Oracle proporciona una implementación de referencia de CachedRowSet. Otros proveedores o controladores JDBC pueden proporcionar implementaciones también.

Tutorial RowSet

Dependiendo de lo que ya hayas hecho y de lo que estés dispuesto a hacer, he estado utilizando Netbeans con su compatibilidad con Beans Binding para una aplicación basada en bases de datos con mucho éxito. Vincula su JTable a una base de datos y genera automáticamente las consultas de JPA.

La mejor forma de llenar jTable con ResultSet

Requisitos previos

1) Resultado El conjunto “rs” se rellena con los datos que necesita. 2) JTable “jTable1” se crea antes de la mano 3) Table Header se implementa antes de la mano

Implementación

  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's 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); } 

Debe crear un TableModel personalizado. Allí puede especificar de dónde y cómo provienen los datos.

Realmente debes entender primero cómo funciona JTable + TableModel y luego seguir una de las respuestas publicadas anteriormente.

Sé que la pregunta es antigua, pero para cualquiera que siga la solución de Adamski, se debe tener cuidado al compartir ResultSet y ResultSetMetadata entre los subprocesos gui y SwingWorker . Obtuve una excepción de estado interno inconsistente al usar este enfoque con SQLite. La solución es cargar cualquier metadato en campos privados antes de ejecutar SwingWorker y tener las funciones getter (getColumnName etc.) para devolver los campos.

Estoy dando un pequeño método para mostrar los datos de la tabla de la base de datos en JTable. Solo debe pasar el conjunto de resultados de la tabla de la base de datos como parámetro.

 // 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); } } 

// 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); } }