gpt4 book ai didi

java - SQL 服务器异常 : The result set is closed

转载 作者:行者123 更新时间:2023-11-29 05:43:26 26 4
gpt4 key购买 nike

我正在尝试使用带有 MS 驱动程序 3.0 的 SQLServer 从结果集中填充 jTable。

只要我不关闭结果集、语句或连接,该表就会生成。如果我关闭它们,我的表会回复消息:

com.microsoft.sqlserver.jdbc.SQLServerException: The result set is closed.

我尝试使用“如何使用表格”教程创建我的表格模型。

这是我的表格模型:

TableModel model = new AbstractTableModel() {
private String[] columnName = {"Employee ID", "Job Start", "Job ID", "Oper. ID", "Indir. ID"};

public int getColumnCount() {
return columns;
}

public int getRowCount() {
return rows;
}

public Object getValueAt(int row, int col) {
try {
rs.absolute(row+1);
return rs.getObject(col+1);
} catch (SQLException ex) {
System.err.println(ex);
}
return null;

}
public String getColumnName(int col) {
return columnName[col];
}
};

我的连接最初是在 try with resources block 中完成的,但在试图找到问题时,我将其放入了 try-catch-finally block 中,其中包含 rs.close()、stmt.close() 和连接。关闭()。正如我上面提到的,如果我没有 close 语句它会工作正常,但如果我有它们,那么它会声明结果集在它到达我的表模型中的 getValueAt 方法时关闭。

我的全部代码在这里:

package dashboard;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import org.omg.CORBA.DATA_CONVERSION;


public class Dashboard extends JFrame {



ResultSet rs;
Connection connection;
Statement stmt;
ResultSetMetaData md;
JScrollPane scrollpane;
int columns, rows;
JFrame frame;
String connectionUrl;

@SuppressWarnings("empty-statement")
public Dashboard() throws SQLException {


try {
connection = DriverManager.getConnection(connectionUrl);
stmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(query);

ResultSetMetaData md = rs.getMetaData();

//Count number of rows
rs.last();
rows = rs.getRow();
rs.first();

//Get column Count
columns = md.getColumnCount();



TableModel model = new AbstractTableModel() {
private String[] columnName = {"Employee ID", "Job Start", "Job ID", "Oper. ID", "Indir. ID"};

public int getColumnCount() {
return columns;
}

public int getRowCount() {
return rows;
}

public Object getValueAt(int row, int col) {
try {
rs.absolute(row+1);
return rs.getObject(col+1);
} catch (SQLException ex) {
System.err.println(ex);
}
return null;

}
public String getColumnName(int col) {
return columnName[col];
}
};


JTable table = new JTable(model);
table.setAutoCreateRowSorter(true);

scrollpane = new JScrollPane(table);
getContentPane().add(scrollpane);

frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setTitle("Employee Dashboard");
frame.setBounds(300, 300, 1300, 750);
frame.setResizable(false);
frame.add(scrollpane);
frame.setVisible(true);
} catch (SQLException ex) {
System.err.println(ex);
} finally {
rs.close();
stmt.close();
connection.close();
}

}

public static void main(String[] args) throws InterruptedException, SQLException {

Dashboard me = new Dashboard();

}
}

更新 6-4-13

根据@Reimeus 所说,我最终将所有东西都扔掉并从头开始。我不是积极的,但我认为这是有效的。当我输出 print model.getRowCount() 时,它告诉我它与我的查询具有相同的行。代码在这里:

 DefaultTableModel model = new DefaultTableModel();

ResultSetMetaData meta = rs.getMetaData();
int numberOfColumns = meta.getColumnCount();
while (rs.next()) {
Object[] rowData = new Object[numberOfColumns];
for (int i = 0; i < rowData.length; ++i) {
rowData[i] = rs.getObject(i + 1);

}
model.addRow(rowData);
System.out.println(model.getColumnName(1));

}

我现在遇到的问题是我无法使用表格模型生成表格。这是我认为可行的方法:

 JTable table = new JTable(model);
table.setAutoCreateRowSorter(true);

scrollpane = new JScrollPane(table);
getContentPane().add(scrollpane);

frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.add(scrollpane);
frame.setVisible(true);

在我心里我在想:

DB 到 RSRS转表模型TM 到表表格到滚动面板ScrollPane 到 Jtable

我确信我正在做的事情很愚蠢,但我的知识还不足以识别它。

最佳答案

ResultSet 在调用 TableModel#getValueAt 时关闭,因为 Swing 使用事件模型从 TableModel 中检索元素。这是异步发生的,即不在主 UI 线程上。不要让 StatementResultSet 等数据库资源处于打开状态。这些会对数据库本身造成开销。

根据 JDBC 查询更新 TableModel,然后关闭关联的数据库资源。不要使用 ResultSet 方法来填充模型。

看看Creating a Table Model .它显示了如何使用固定的支持数据来保存 TableModel 的数据。或者可以使用 ArrayList

如果您刚开始,DefaultTableModel 易于使用并且是可变的。稍后您可以继续管理模型的更新,例如 example来自@mKorbel

旁白:使用 PreparedStatement 而不是 Statement 来防止 SQL 注入(inject)攻击

关于java - SQL 服务器异常 : The result set is closed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16678851/

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