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 が正当であることは保証できますが、2 回目に呼び出されたときに 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());
        }
    }
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 に答える