0

好的,所以我有一段代码被多次调用。然而,在一些测试中,我注意到我的 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 中获取行并获得正确的结果 - OK
  • 从表中删除上面特定 sql 使用的所有行,这意味着 ResultSet 下次不应该返回任何内容。
  • 再次尝试获取(现在它应该返回 0 行)但它返回与步骤 1 中完全相同的行,即使数据库表是空的。

ResultSet 应该在使用后关闭还是关闭,或者我错过了什么?即使数据库中没有任何内容,我也会从 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());
        }
    }
4

2 回答 2

2

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

据我所知,这个小代码示例将演示它。

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

这似乎是您所期望的。

于 2012-12-15T03:13:45.840 回答
0

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

试一试

        connection.rollback();

或者

        connection.commit();

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

于 2012-12-15T03:15:20.040 回答