Не могу вывести данные из базы данных в JTable
Подскажите, имеется такой код, как мне из базы данных вывести ВСЕ данные в JTable? Чтобы я ни делал, в JTable выводится только одна строчка данных и названия столбцов.
import com.mysql.cj.protocol.Resultset;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.sql.*;
public class Wydatki implements StartInterface{
private Object[][] data;
private Object[] columnsHeader;
DefaultTableModel tableModel;
JTable jtable;
JScrollPane scrollPane = new JScrollPane();
JFrame jframe = new JFrame();
JPanel jpanel = new JPanel();
public Wydatki(String NickName,String Rok,String Miesiac){
StartInterface.StartJMenu(jframe,NickName);
jframe.add(jpanel);
jframe.setTitle("Wydatki");
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException classNotFoundException) {
classNotFoundException.printStackTrace();
}
String username = "root";
String password = "QWERTY123";
String connectionURL = "jdbc:mysql://localhost:3306/centus_database";
try {
Connection conn = DriverManager.getConnection(connectionURL, username, password);
String sql = "select dzien,Zywnosc,Mieszkianie,Media,Transport,Ubrania,Rachunki,Rozrywka,Suma_wydatkow from wydatki where NickName = ? and rok = ? and miesiac = ?";
PreparedStatement prestmt = conn.prepareStatement(sql);
prestmt.setString(1,NickName);
prestmt.setString(2,Rok);
prestmt.setString(3,Miesiac);
ResultSet resultSet = prestmt.executeQuery();
while(resultSet.next())
{
Object[][] data = new Object [][]{
{resultSet.getString("dzien"),resultSet.getString("Zywnosc"),resultSet.getString("Mieszkianie"),
resultSet.getString("Media"),resultSet.getString("Transport"),
resultSet.getString("Ubrania"),resultSet.getString("Rachunki"),resultSet.getString("Rozrywka"),resultSet.getString("Suma_wydatkow")}
};
columnsHeader = new String[] {"Dzien","Zywnosc","Mieszkanie","Media","Transport","Ubrania","Rachunki","Rozrywka","Suma"};
jtable = new JTable(data, columnsHeader);
scrollPane = new JScrollPane(jtable);
jtable.setFillsViewportHeight(true);
jpanel.setLayout(new BorderLayout());
jpanel.add(jtable.getTableHeader(), BorderLayout.PAGE_START);
jpanel.add(jtable, BorderLayout.CENTER);
jpanel.setVisible(true);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
Ответы (1 шт):
ResultSet чем-то напоминает итератор. У вас есть какое-то количество данных, однако, представьте, что они записаны построчно. Кроме того, есть курсор, который указывает на текущую строку (строку , на которой вы остановились, выполняя чтение). У вас в руках есть только 1 механизм для чтения этих данных - вызов next , который передвинет курсор на следующую строку, если она имеется. Та строка, на которой находится курсор, и приходит к вам на обработку. Но курсор единовременно указывает только на одну строку, а вам нужно прочитать все строки. Поэтому вы используете цикл. В теле цикла вы получите все строки поочередно. Все хорошо, но таблица , в которую вы пишите, пересоздается в теле цикла. Т.е. вы всегда при 1 итерации добавляете в новосозданную таблицу 1 строку. Следующий цикл - новая таблица с добавлением одной строки. Поскольку перменная для таблицы одна, то таблица, созданная на предыдущей итерации больше не имеет ссылок и ее удаляет сборщик мусора.
К сожалению, это далеко не единственная проблема этого кода. Я немного подправил класс, но привести его в нормальный вид невозможно, для этого нужно рефакторит код всего приложения.
import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import java.util.ArrayList;
import java.util.List;
public class Wydatki extends JFrame {
private static final long serialVersionUID = 6846421395193283567L;
private final static String username = "root";
private final static String password = "QWERTY123";
private final static String connectionURL = "jdbc:mysql://localhost:3306/centus_database";
private final static String sql = "select dzien,Zywnosc,Mieszkianie,Media,Transport,Ubrania,Rachunki,"
+ "Rozrywka,Suma_wydatkow from wydatki where NickName = ? and rok = ? and miesiac = ?";
private final static Object[] columnsHeader = new String[]{"Dzien", "Zywnosc", "Mieszkanie", "Media",
"Transport", "Ubrania", "Rachunki", "Rozrywka", "Suma"};
private final static Connection connection;
static {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(connectionURL, username, password);
} catch (ClassNotFoundException | SQLException ex) {
throw new RuntimeException(ex);
}
}
public Wydatki(String nickName, String rok, String miesiac) {
try {
init(nickName, rok, miesiac);
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
private void init(String nickName, String rok, String miesiac) throws SQLException {
//это МАКСИМАЛЬНО странная строка кода
StartInterface.StartJMenu(this, nickName);
JTable jtable = new JTable(findData(nickName, rok, miesiac), columnsHeader);
jtable.setFillsViewportHeight(true);
JPanel jpanel = new JPanel();
jpanel.setLayout(new BorderLayout());
jpanel.add(jtable.getTableHeader(), BorderLayout.PAGE_START);
jpanel.add(jtable, BorderLayout.CENTER);
this.add(jpanel);
this.setTitle("Wydatki");
this.setVisible(true);
}
private Object[][] findData(String nickName, String rok, String miesiac) throws SQLException {
PreparedStatement prestmt = connection.prepareStatement(sql);
prestmt.setString(1, nickName);
prestmt.setString(2, rok);
prestmt.setString(3, miesiac);
ResultSet resultSet = prestmt.executeQuery();
final List<Object[]> tableContent = new ArrayList<>();
while (resultSet.next()) {
final Object[] data = new Object[]{
resultSet.getString("dzien"), resultSet.getString("Zywnosc"),
resultSet.getString("Mieszkianie"), resultSet.getString("Media"),
resultSet.getString("Transport"), resultSet.getString("Ubrania"),
resultSet.getString("Rachunki"), resultSet.getString("Rozrywka"),
resultSet.getString("Suma_wydatkow")
};
tableContent.add(data);
}
return tableContent.toArray(new Object[tableContent.size()][]);
}
}