ResultSet被重用

时间:2012-12-15 00:40:54

标签: 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似乎不是从它创建的。

EDIT(连接初始化代码)

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());
        }
    }

2 个答案:

答案 0 :(得分:1)

我希望您为连接启用了自动提交功能。

就我能理解你的问题而言,这个小代码示例将演示它。

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...

这是您的期望。

答案 1 :(得分:0)

您可能在事务中,如果您提交或回滚当前事务,您将看到数据库的当前状态。

尝试

        connection.rollback();

        connection.commit();

在查询之前,或打开自动提交。