我正在尝试创建一个向我显示数据库中所有电影名称的帧,他们在框架中选择一行以执行另一个查询。
我有一个结果集(RS(,该结果集接收了查询执行的结果以选择电影的名称。之后,我使用SQLTableModel中的RS来创建JTable并在框架中显示。桌子向我展示了我数据库中所有电影的名称。一切都很好。
但是,当我选择一行时,我使用相同的rs接收另一个查询,然后在数据库中选择我在JTable中选择的电影的所有信息,并且会得到一些erros。p> firts,我在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: %sn", 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的连接很昂贵,因此保持这种连接也很昂贵。因此,请尽可能快地调用DB,尽可能短。在内存中获得数据后,您可以根据需要进行操作。