java - 结果集被重用

标签 java mysql jdbc resultset

好的,我有一段被调用了多次的代码。然而,在一些测试过程中,我注意到根据数据库,我的 ResultSet 返回错误。经过进一步调查,我注意到它以某种方式被重用。值得一提的是,当我重新启动程序时,它会获取正确的结果。 SQL 始终相同。

我的代码:

PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1, packet.getUserId());
ResultSet dbResult = ps.executeQuery();

while(dbResult.next())
{
    System.out.println("There were items!" );
    Item item = new Item();
    item.setItemType(dbResult.getInt(1));
    item.setFromUser(dbResult.getString(2));
    item.setItemMessage(dbResult.getString(3));
    toReturn.add(item);
}

这是我的测试顺序:

  • 从 ResultSet 中获取行一次并获得正确的结果 - 好的
  • 从表中删除上述特定 SQL 使用的所有行,这意味着 ResultSet 下次不应返回任何内容。
  • 尝试再次提取(现在应该返回 0 行),但它会返回与步骤 1 中完全相同的行,即使数据库表为空。

结果集是否应该在使用后关闭或进行其他操作,或者我缺少什么? 即使数据库中没有任何内容,我也从 ResultSet 中获取结果。我可以保证 SQL 是合法的,但 ResultSet 似乎不是在第二次调用时从中创建的。

编辑(连接初始化代码)

public class DBFactory 
{
    protected String databaseName = null;
    protected String username = null;
    protected String password = null;
    protected Connection connection = null;
    protected Statement statement = null;

    protected DBFactory( String databaseName, String username, String password)
    {
        this.databaseName = databaseName;
        this.username = username;
        this.password = password;
    }

    protected void initConnection()
    {
        if (databaseName == null || username == null || password == null)
            throw new IllegalStateException();

        try 
        {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            this.connection = DriverManager.getConnection(this.databaseName, this.username, this.password);
            this.statement = this.connection.createStatement();
        } 
        catch (Exception e) 
        {
            System.out.println("DBFactory " + e.getMessage());
        }
    }

最佳答案

我希望您已关闭连接的自动提交。

据我了解您的问题,这个小代码示例将演示它。

package org.yi.happy.mysql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class RepeatQuery {
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver").newInstance();

        setupDatabase();

        System.out.println("opening database...");
        Connection connection = openConnection();
        connection.setAutoCommit(false);

        queryDatabase(connection);

        deleteRecords();

        queryDatabase(connection);

        connection.close();
    }

    private static Connection openConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost/test", null,
                null);
    }

    private static void setupDatabase() throws SQLException {
        Connection conn = openConnection();

        System.out.println("doing insert on another connection...");
        PreparedStatement stmt = conn
                .prepareStatement("insert into strings(id, value) values(?, ?)");

        stmt.setInt(1, 1);
        stmt.setString(2, "test");
        stmt.execute();

        stmt.setInt(1, 2);
        stmt.setString(2, "data");
        stmt.execute();

        stmt.close();
        conn.close();
    }

    private static void deleteRecords() throws SQLException {
        Connection conn = openConnection();
        System.out.println("doing delete on another connection...");
        PreparedStatement stmt = conn.prepareStatement("delete from strings");
        stmt.execute();

        stmt.close();
        conn.close();
    }

    private static void queryDatabase(Connection connection)
            throws SQLException {
        System.out.println("doing query...");
        PreparedStatement ps = connection
                .prepareStatement("select id, value from strings");
        ResultSet dbResult = ps.executeQuery();

        while (dbResult.next()) {
            int id = dbResult.getInt(1);
            String value = dbResult.getString(2);
            System.out.println(id + " <=> " + value);
        }
    }
}

上面的输出是

doing insert on another connection...
opening database...
doing query...
2 <=> data
1 <=> test
doing delete on another connection...
doing query...
2 <=> data
1 <=> test

如果我改变

            connection.setAutoCommit(false);

阅读

            connection.setAutoCommit(true);

输出变为

doing insert on another connection...
opening database...
doing query...
2 <=> data
1 <=> test
doing delete on another connection...
doing query...

这似乎是您所期望的。

关于java - 结果集被重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13888209/

相关文章:

java - jsp和java应用程序之间的通信

java - 为什么使用双重的for循环无法终止

Oracle 通过 JDBC 直接加载 INSERT?

Java 中 MySQL 查询 INSERT

java - 如何修复 java 中对特定行和列求和的加法?

java - java中两个矩形之间的碰撞检测

mysql - 连接 MySQL 服务器的独立库

c# - 在日期时间 c# 中格式化字符串以插入 MYSQL 日期时间列

mysql - 合并2个时间序列

performance - 与 Hibernate 或 JDBC 相比,JPA 批处理的性能很糟糕