Операция не разрешена после закрытия ResultSet после использования ResultSet в AbstractTableModel - PullRequest
0 голосов
/ 05 июля 2019

Я пытаюсь создать фрейм, в котором отображаются все имена фильмов в моей базе данных, и они выбирают строку в фрейме для выполнения другого запроса.

У меня есть ResultSet (rs), который получает результат выполнения запроса для выбора названия фильмов. После этого я использую rs в моем SQLTableModel, который я использую, чтобы создать JTable и показать в моем фрейме. В таблице показано название всех фильмов, которые есть в моей базе данных. Все отлично работает.

Но когда я выбираю строку, я использую те же самые rs для получения другого запроса, который поступает в мою базу данных, чтобы выбрать всю информацию о фильме, который я выбрал в моей JTable, и я получаю некоторые ошибки.

Во-первых, строка, которую я выбрал в JTable, теряет значение (название фильма). Но в остальных рядах ничего не происходит. Во-вторых, моя консоль показывает мне ошибку, которая пришла из моего SQLTableModel, в функции «getValueAt», говоря, что «Erro: # 0 Операция не разрешена после закрытия ResultSet».

Я искал какое-то решение здесь в 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();
        }
    }

}

1 Ответ

1 голос
/ 05 июля 2019

Всегда используйте структуру памяти, такую ​​как ArrayList или Map, для кэширования результата, полученного из БД.Поскольку подключение к БД стоит дорого, поддержание этого соединения также дорого.Итак, вызов БД как можно быстрее, как можно короче.Как только вы получили данные в памяти, вы можете свободно манипулировать ими.

...