gpt4 book ai didi

java - 在 AbstractTableModel 中使用 ResultSet 后,ResultSet 关闭后不允许进行操作

转载 作者:行者123 更新时间:2023-12-02 03:25:33 28 4
gpt4 key购买 nike

我正在尝试创建一个框架来显示数据库中的所有电影名称,然后他们选择框架中的一行来执行另一个查询。

我有一个 ResultSet (rs),它接收查询执行的结果以选择电影名称。之后,我使用 SQLTableModel 中的 rs 来创建 JTable 并在我的框架中显示。该表显示了数据库中所有电影的名称。一切都很好。

但是,当我选择一行时,我使用相同的 rs 接收另一个查询,该查询在我的数据库中选择我在 JTable 中选择的电影的所有信息,并且出现一些错误。

首先,我在 JTable 中选择的行丢失了值(电影名称)。但在其他行中什么也没有发生。其次,我的控制台在函数“getValueAt”中向我显示来自 SQLTableModel 的错误,指出“错误:ResultSet 关闭后不允许#0 操作”。

我在stackoverflow上搜索了一些解决方案,但没有成功。

我做了一些测试。如果我的 ResultSet (rs) 在我的 SQLTableModel 中使用它之前收到多个查询,则一切正常。但是当我在 SQLTableModel 中使用它之后,如果我尝试再次使用它,我会收到我提到的错误。

FrameCliente.java

public class FrameCliente {

JFrame frameCliente;
JTable table;

BancoDeDados bd;
ResultSet rs;

public FrameCliente() {
bd = new BancoDeDados();
frameCliente = new JFrame();
table = new JTable();
rs = bd.listar("SELECT fil_nome Nome FROM filme");
table.setModel(new SQLTableModel(rs));

table.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(table.getSelectedRowCount() > 0) {
rs = bd.listar(" SELECT * FROM filme WHERE fil_nome = '" + table.getValueAt(table.getSelectedRow(), 0) + "'");
}
}
});

frameCliente.add(new JScrollPane(table));
frameCliente.setTitle("Filmes");
frameCliente.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameCliente.setSize(800, 300);
frameCliente.setLocationRelativeTo(null);
frameCliente.setVisible(true);
}

}

SQLTableModel.java

public class SQLTableModel extends AbstractTableModel {

private ResultSet rs;
private ResultSetMetaData rsmd;
private int numberOfRows=0;

public SQLTableModel(ResultSet rs){
this.rs = rs;
try { //Todos os métodos são privado e isso gera exceção.
rsmd = this.rs.getMetaData();
//Navegar para encontrar a ultima linha, para saber quantas linhas a tabela possui.
this.rs.last(); // Pega a ultima linha;
numberOfRows = rs.getRow(); //Devolve a linha, no caso, a ultima.
this.rs.beforeFirst(); //Retorna para a primeira linha.
}catch(SQLException sqle){
System.out.printf("Erro: #%d [%s]\n",
sqle.getErrorCode(), sqle.getMessage());
}

}


@Override
public int getRowCount() {
// TODO Auto-generated method stub
return numberOfRows;
}

@Override
public int getColumnCount() {
// TODO Auto-generated method stub
try {
return rsmd.getColumnCount();
}catch(SQLException sqle){
System.out.printf("Erro: #%d [%s]\n",
sqle.getErrorCode(), sqle.getMessage());
return 0; // Se der exceção não retorna nenhuma coluna;
}
}

@Override
public String getColumnName(int column) {
String ColumnName = "";
try {
ColumnName = rsmd.getColumnLabel(column+1);
}catch(SQLException sqle){
System.out.printf("Erro: #%d [%s]\n",
sqle.getErrorCode(), sqle.getMessage());
}
return ColumnName;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
Object dado = null;
try {
rs.absolute(rowIndex+1);
dado = rs.getObject(columnIndex+1);
}catch(SQLException sqle){
System.out.printf("Erro: #%d [%s]\n",
sqle.getErrorCode(), sqle.getMessage());
}
return dado;
}

@Override
public Class<?> getColumnClass(int columnIndex) {
String className;
try {
className = rsmd.getColumnClassName(columnIndex+1);
return Class.forName(className);
}catch(SQLException sqle){
System.out.printf("Erro: #%d [%s]\n",
sqle.getErrorCode(), sqle.getMessage());
} catch (ClassNotFoundException cnfe) {
System.out.printf("Erro: %s\n", cnfe.getMessage());
}
return null;
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}

public void atualizarTabela() {
fireTableDataChanged();
}


}

BancoDeDados

public class BancoDeDados {
private Connection con = null;
private Statement sta = null; //faz consultas
private ResultSet rset = null; //armazenas as info pra trabalhar com elas depois - resultado do select

public BancoDeDados() {
this.conectar();
}


public void conectar() {
String servidor = "jdbc:mysql://localhost:3306/cinema?useSSL=true&useTimezone=true&serverTimezone=UTC";
String usuario = "root";
String senha = "coreduo2";
String driver = "com.mysql.cj.jdbc.Driver";

try {

//Class.forName(driver);
this.con = DriverManager.getConnection(servidor, usuario, senha);
this.sta = this.con.createStatement();
}
catch(Exception e)
{
System.out.println("Error " + e.getMessage());
}
}

public boolean estaConectado() {
if (con != null) {
return true;
}
else {
return false;
}
}

public void desconecte() {
try {
con.close();
System.out.println("Conexao com banco encerrado");
}
catch(SQLException e) {
System.out.println("Erro: " + e.getMessage());
}
}

public ResultSet listar(String query) {
try {
return sta.executeQuery(query);
//this.sta = this.con.createStatement();
/*while (this.rset.next()) {
System.out.println("ID: " + rset.getString("fil_codigo") + " Nome: " + rset.getString("fil_nome") + " Duração: " + rset.getString("fil_duracao"));
}*/

}
catch(SQLException e) {
System.out.println("Erro "+ e.getMessage());
return null;
}
}

public void inserir(String query) {
try {
this.sta.executeUpdate(query);
}
catch(SQLException e) {
System.out.println("Erro"+ e.getMessage());
}

}

public void excluir(String query) {
try {
this.sta.executeUpdate(query);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void editar(String query) {
try {
this.sta.executeUpdate(query);
}
catch (SQLException e) {
e.printStackTrace();
}
}

}

最佳答案

始终使用ArrayList或Map等内存结构来缓存从DB获取的结果。由于与数据库的连接成本很高,因此保持此连接也很昂贵。因此,尽可能快、尽可能短地调用 DB。一旦将数据存入内存,您就可以按照自己的意愿自由操作。

关于java - 在 AbstractTableModel 中使用 ResultSet 后,ResultSet 关闭后不允许进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56908492/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com