0

この問題に適切なタイトルを付けるには、私の創造性の欠如をお許しください。

こんにちは、私はこの問題を理解しようと過去 3 時間を費やしました。私はそれを理解したと思いますが、それに対する解決策はまだ私を逃れています。私はこの非常に単純なコードを持っています。

    Statement stmt = db.getStatement();
    ResultSet queryResult = stmt.executeQuery("SELECT * FROM users");

    while(queryResult.next()) {
        username = queryResult.getString("username");
        password = queryResult.getString("password");
        privilege = queryResult.getInt("privilege");

        queryResult = stmt.executeQuery("SELECT * FROM division");
        while(queryResult.next()) {}

        users.add(new User(username, password, privilege));
    }

さて、このコードの一部は、私のコードの問題が何であるかを説明するために単純化されています。明らかに、何も含まれていないwhileループはありません。

データベースから何かをフェッチしたいときはいつでも、結果セットを 1 つのループ内でしか実行できないことに気付きました。"nested-resultset-loop" を記述すると、"Operation... ResultSet closed"、"Cannot find column 'username'"、またはその他のエラーが発生します。

データベースからすべてを取得するために、DAO コード全体でこれらのネストされた結果セット ループが多数あります。私は MySQL にあまり詳しくないので、これが単純な解決策でした (このプログラムを実行する時間がほとんどありません)...以前は PHP で同様のことをしていたので。

このコードが良い設計だと言っているわけではありませんが、時間の都合上、現時点では優れたクラス設計についてあまり気にしていませんしたがって、設計の選択が不十分であっても、あなたが考えている解決策は歓迎されます。

別の解決策は、すべてを単一のループに分割することです。これは機能する傾向があるためです (非常に簡単です)。しかし、それは多くのコードを変更することを意味し、これをバックアップ計画にしたいと思います.

4

2 に答える 2

4

そのように結果セットをインターリーブすることはできません。API ドキュメントを参照してください。

デフォルトでは、Statement オブジェクトごとに 1 つの ResultSet オブジェクトのみを同時に開くことができます。したがって、ある ResultSet オブジェクトの読み取りが別の ResultSet オブジェクトの読み取りとインターリーブされている場合、それぞれが異なる Statement オブジェクトによって生成されている必要があります。Statement インターフェースのすべての実行メソッドは、開いているステートメントの現在の ResultSet オブジェクトが存在する場合、そのオブジェクトを暗黙的に閉じます。

クエリごとに個別のステートメントを作成しても問題ないと思います。私が見た通常の方法は、DAO メソッドを可能な限り単純にして再利用可能に保つために、クエリごとに個別の DAO メソッドを用意することです。(これは、DAO がトランザクションの境界を担当するのではなく、サービスなどのより高いレベルのコンポーネントがトランザクションの内容を制御することを意味します。)

于 2012-12-15T21:21:33.407 に答える
0

問題を解決するには、ネストされたループの値を同じ ResultSet に割り当てないでください。

于 2012-12-15T21:21:44.680 に答える