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

前端之家收集整理的这篇文章主要介绍了Java JDBC MySQL异常:“ResultSet关闭后不允许操作”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我已经在这方面工作了将近一天半,我似乎无法解决这个错误.我不知道为什么要关闭ResultSet.也许你们中的一些人可以帮助我.

MySQLDatabase:

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,password));
    }

}

MysqLDonation

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 password) {
        super(host,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)

有了这些信息,让我说这确实有用,我得到了我的信息以及游戏中的内容,但它重复了,就像用户永远不会从查询删除一样,因此它给了他们无限的奖励.如果您需要更多信息,请随时询问.

最佳答案
运行“删除查询时,将使用“选择”查询中使用的相同“语句”.当您在同一个Statement上重新执行时,前一个ResultSet将关闭.

为避免这种情况,您应该在每次执行查询时创建一个新的Statement.所以删除statement = connection.createStatement();从MysqLDatabase类中的connect()方法,并将该类中的所有语句替换为connection.createStatement().您也可以选择完全删除私有变量语句.

你可以阅读更多关于它here.

原文链接:https://www.f2er.com/mysql/434282.html

猜你在找的MySQL相关文章