Java JDBC MySQL异常:“在ResultSet关闭后不允许进行操作”?mysql-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

2020-05-13 14:40:07 322 1

我已经为此工作了将近一天半,但似乎无法解决此错误。我不知道为什么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) 有了这些信息,我可以说这确实有效,我得到了我的信息,但不是游戏中的内容,而是重复出现的内容,就像用户从未从查询中删除一样,因此可以给他们带来无限的回报。如果您需要更多信息,请随时询问。

取消 提交回答
全部回答(1)
  • 保持可爱mmm
    2020-05-13 14:40:20

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

    为了避免这种情况,您应该在Statement每次执行查询时创建一个新的。因此,statement = connection.createStatement();从类中的connect()方法中删除,并将MySQLDatabase该类中的所有内容替换statement为connection.createStatement()。您也可以选择statement完全删除私有变量。来源:stack overflow

    0 0
相关问答

1

回答

Java中检查性异常是什么?

2021-11-17 08:11:22 122浏览量 回答数 1

1

回答

java中的可检查异常是什么?

2021-11-02 21:02:51 133浏览量 回答数 1

0

回答

您好java性能问题:有没有比较字符串是否相等的最快方法?

2021-11-07 00:39:14 133浏览量 回答数 0

0

回答

请问java性能问题:如何优化向HashMap插入元素的速度?

2021-11-12 17:18:18 127浏览量 回答数 0

0

回答

请问java中常用的性能调优诊断工具都有哪些,请帮忙提供一下?

2021-11-06 22:35:44 80浏览量 回答数 0

0

回答

请问java中使用BigDecimal计算操作性能最优的做法是什么?

2021-11-07 15:42:19 200浏览量 回答数 0

1

回答

java性能问题:有没有比较字符串是否相等的最快方法?

2021-11-06 16:21:40 155浏览量 回答数 1

1

回答

java性能问题:如何优化向HashMap插入元素的速度?

2021-11-06 15:41:34 202浏览量 回答数 1

1

回答

java中常用的性能调优诊断工具都有哪些,请帮忙提供一下?

2021-11-06 10:24:39 148浏览量 回答数 1

1

回答

java中使用BigDecimal计算操作性能最优的做法是什么?

2021-11-06 16:35:15 217浏览量 回答数 1
66
文章
12595
问答
问答排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载