Java JDBC MySQL异常:“在ResultSet关闭后不允许进行操作”

我已经为此工作了将近一天半,但似乎无法解决此错误。我不知道为什么ResultSet被关闭。也许有些人可以帮助我。

MySQL数据库:

package net.gielinor.network.sql;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public abstract class MySQLDatabase {

private String host;

private String database;

private String username;

private String password;

private Connection connection = null;

private Statement statement;

public MySQLDatabase(String host, String database, String username, String password) {

this.host = host;

this.database = database;

this.username = username;

this.password = password;

}

public abstract void cycle() throws SQLException;

public abstract void ping();

public void connect() {

try {

Class.forName("com.mysql.jdbc.Driver").newInstance();

connection = DriverManager.getConnection(String.format("jdbc:mysql://%s/%s", host, database), username, password);

statement = connection.createStatement();

} catch (Exception e) {

e.printStackTrace();

}

}

public void ping(String table, String variable) {

try {

statement.executeQuery(String.format("SELECT * FROM `%s` WHERE `%s` = 'null'", table, variable));

} catch (Exception e) {

connect();

}

}

public ResultSet query(String query) throws SQLException {

if (query.toLowerCase().startsWith("select")) {

return statement.executeQuery(query);

} else {

statement.executeUpdate(query);

}

return null;

}

public Connection getConnection() {

return connection;

}

}

MySQLHandler

package net.gielinor.network.sql;

import java.io.FileInputStream;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

import net.gielinor.network.sql.impl.MySQLDonation;

public class MySQLHandler extends Thread {

private static final MySQLHandler mysqlHandler = new MySQLHandler();

public static MySQLHandler getMySQLHandler() {

return mysqlHandler;

}

private static List<MySQLDatabase> updateList;

private static String host;

private static String database;

private static String username;

private static String password;

@Override

public void run() {

while (true) {

for (MySQLDatabase database : updateList) {

try {

if (database.getConnection() == null) {

database.connect();

} else {

database.ping();

}

database.cycle();

} catch (Exception ex) {

ex.printStackTrace();

}

try {

Thread.sleep(10000);

} catch (Exception ex) {

}

}

}

}

private static void loadProperties() {

Properties p = new Properties();

try {

p.load(new FileInputStream("./sql.ini"));

host = p.getProperty("host");

database = p.getProperty("database");

username = p.getProperty("username");

password = p.getProperty("password");

} catch (Exception ex) {

System.out.println("Error loading MySQL properties.");

}

}

public static String getHost() {

return host;

}

static {

loadProperties();

updateList = new ArrayList<MySQLDatabase>();

updateList.add(new MySQLDonation(host, database, username, password));

}

}

MySQL捐赠

package net.gielinor.network.sql.impl;

import java.sql.ResultSet;

import java.sql.SQLException;

import net.gielinor.game.model.player.Client;

import net.gielinor.game.model.player.PlayerHandler;

import net.gielinor.game.model.player.PlayerSave;

import net.gielinor.network.sql.MySQLDatabase;

public final class MySQLDonation extends MySQLDatabase {

public MySQLDonation(String host, String database, String username, String password) {

super(host, database, username, password);

}

@Override

public void cycle() throws SQLException {

ResultSet results = query("SELECT * FROM `gieli436_purchases`.`donations`");

if (results == null) {

return;

}

while (results.next()) {

String username = results.getString("username").replace("_", " ");

System.out.println("name=" + username);

Client client = (Client) PlayerHandler.getPlayer(username.toLowerCase());

System.out.println(client == null);

if (client != null && !client.disconnected) {

int creditamount = results.getInt("creditamount");

if (creditamount <= 0) {

continue;

}

handleDonation(client, creditamount);

query(String.format("DELETE FROM `gieli436_purchases`.`donations` WHERE `donations`.`username`='%s' LIMIT 1", client.playerName.replaceAll(" ", "_")));

}

}

}

@Override

public void ping() {

super.ping("donations", "username");

}

private void handleDonation(Client client, int creditamount) throws SQLException {

client.credits = (client.credits + creditamount);

client.sendMessage("Thank you for your purchase. You have received " + creditamount + " store credits.");

PlayerSave.save(client);

}

}

异常发生在这里:在MySQLDonation的while循环中,实际的堆栈跟踪是这样的:

java.sql.SQLException: Operation not allowed after ResultSet closed

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)

at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)

at com.mysql.jdbc.ResultSetImpl.checkClosed(ResultSetImpl.java:794)

at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7077)

at net.gielinor.network.sql.impl.MySQLDonation.cycle(Unknown Source)

at net.gielinor.network.sql.MySQLHandler.run(Unknown Source)

有了这些信息,我可以说这 确实

有效,我得到了我的信息,但不是游戏中的内容,而是重复出现的内容,就像用户从未从查询中删除一样,因此可以给他们带来无限的回报。如果您需要更多信息,请随时询问。

回答:

运行Delete查询时,请使用与查询中相同StatementSelect查询。当您在同一位置重新执行时Statement,前一个ResultSet将关闭。

为了避免这种情况,您应该在Statement每次执行查询时创建一个新的。因此,statement =

connection.createStatement();从类中的connect()方法中删除,并将MySQLDatabase该类中的所有内容替换statementconnection.createStatement()。您也可以选择statement完全删除私有变量。

您可以在此处了解更多信息。

以上是 Java JDBC MySQL异常:“在ResultSet关闭后不允许进行操作” 的全部内容, 来源链接: utcz.com/qa/401364.html

回到顶部