Java 如何重用JDBC语句和自动关闭结果集?

Java 如何重用JDBC语句和自动关闭结果集?,java,mysql,jdbc,Java,Mysql,Jdbc,iam正在进行一个项目,该项目将有许多语句连接到DB 我希望重用语句,而不是每次连接都创建新语句 最重要的是,我不想在使用后关闭每个结果集 我想在重用语句之前关闭语句上的结果集 我的代码是这样的 ArrayList<Statement> BackStatements = new ArrayList(); int lastStatementIndex = 0; private Statement GetStatement() throws SQLException { Sta

iam正在进行一个项目,该项目将有许多语句连接到DB 我希望重用语句,而不是每次连接都创建新语句 最重要的是,我不想在使用后关闭每个结果集

我想在重用语句之前关闭语句上的结果集

我的代码是这样的

ArrayList<Statement> BackStatements = new ArrayList();
int lastStatementIndex = 0;

private Statement GetStatement() throws SQLException {
    Statement SM;
    int MaxStatements = 5;
    if (BackStatements.size() < MaxStatements) {
        SM = Connection.createStatement();
        BackStatements.add(SM);
        lastStatementIndex = BackStatements.size() - 1;
    } else {
        lastStatementIndex = lastStatementIndex + 1;
        if (lastStatementIndex == MaxStatements) {
            lastStatementIndex = 0;
        }
        SM = BackStatements.get(lastStatementIndex);
     /// i want to close resultset generated by SM now and i do this before return this SM
        SM.getResultSet().close();

    }

    System.out.println("Last Index:" + lastStatementIndex + "---- Size:" + BackStatements.size());
    return SM;
}

在我看来,这是一种糟糕的风格。强制关闭最旧的语句和结果集时,无法确保它不再被使用

你没有暗示在哪里发生了这种情况,但我认为这可能是原因


如果你想使用一个语句池,那么你应该在使用后主动将它们返回。

这通常是个坏主意。语句是一个接口,实际类可以是JDBC驱动程序返回的任何内容。 通常,不能将一个语句类重新用于另一种类型。例如 oracle JDBC的CallableStatement和PreparedStatement不兼容

对于ResultSet,至少在某些情况下,关闭它会释放数据库游标。resultSet.close的延迟会对数据库服务器容量产生负面影响


一般来说,如果您的JDBC驱动程序支持连接池,这是一个不错的选择。一般来说,网络往返比创建报表要昂贵得多

您应该使用驱动程序提供的语句缓存,而不是构建自己的语句缓存。例如,在Oracle JDBC精简驱动程序中,有一个隐式语句缓存,负责优化语句和游标的分配和释放方式。它需要打开。医生是。要启用它,只需将属性oracle.jdbc.implicitStatementCacheSize设置为一个值(例如10),该值通常是语句缓存的一个良好大小。

您似乎正在尝试像连接池中的jdbc连接一样重用语句。。!!但你的方法处理得不恰当。如果我没有正确地理解你,请纠正我是的,你是对的,我希望方法重用语句或实现这一点的一般想法,但你没有分享你的代码语句是如何创建的?你应该为此使用一个连接池,而不是尝试使用你自己的连接池。许多厂商的JDBC驱动程序已经支持这一点,还有一些外部软件包,比如ApacheDBCP。包括Javadoc在内,没有人说过创建新语句会关闭旧的结果集。只有关闭旧的ResultSet或旧语句才能做到这一点。SM.getResultSet.close的问题是您正在第二次请求结果集,正如错误消息所说的那样。您当然应该删除它,但仍然应该关闭旧的结果集。但正如上面所说的,您当然应该使用现有的连接池实现,而不是尝试使用自己的连接池实现。无论如何,您几乎肯定应该使用PreparedStatements。
Caused by: java.sql.SQLException: ResultSet already requested