2

Java チュートリアルでは、次のことができると述べていますtry-with-resources

try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);
    ...
} catch (SQLException e) {
    ...
}

このチュートリアルでは、 が閉じられることはありません。したがって、次のようにインターフェイスも実装しているため、ResultSetを含めたいと思います。ResultSetAutoCloseable

try (Statement stmt = con.createStatement(); 
     ResultSet rs = stmt.executeQuery(query)) {
    ...
} catch (SQLException e) {
    ...
}

これは問題なく動作しますが、クエリを実行する前にPreparedStatementsいくつかの値を設定できるようにしたいと考えています。

String name = "Ian";
try (PreparedStatement pstmt = getPreparedStatement(con, stmt); 
     pstmt.setString(1, name);
     ResultSet rs = pstmt.executeQuery(query)) {
    ...
} catch (SQLException e) {
    ...
}

変数の割り当てのみが許可されているため (私は推測しています)、これによりさまざまなコンパイル エラーが発生します。

try-with-resources同じブロックでこれをきちんと行う方法はありますか?

私はすでに考えました:

  1. ネストされた try-with-resources (これは私が避けようとしているものです)。そうすることに「悪い」ことは何もないことに気づきました。読みやすくするためにこれをやりたいだけです。

次の場合を考慮してください。

try (MyObject1 o1 = new MyObject1()) {
    o1.setSomeValue();
    try (MyObject2 o2 = new MyObject2(o1)) {
        o2.setSomeValue();
        try (MyObject3 o3 = new MyObeject3(o2) {
            o3.setSomeValue();
            // do work here
        }
    }
} catch (Exception e) {
    ...
}

try (MyObject1 o1 = new MyObject1();
     o1.setSomeValue();
     MyObject3 o2 = new MyObeject2(o1);
     o2.setSomeValue();
     MyObject3 o3 = new MyObeject3(o2);
     o3.setSomeValue()) {

    // do work here
} catch (Exception e) {
    ...
}
  1. メソッドにオブジェクトをsetString()返させ、代入に含める
  2. 接続を作成し、それに応じてパラメーターを設定する、ある種のヘルパー メソッドを作成します。

何かのようなもの:

public PreparedStatement createPreparedStatement(Connection con, String stmt, Object ... params) {

}
4

3 に答える 3

3

私はあなたが意味したと思いますConnection.prepareStatement()

ResultSet を閉じることは API-Doc によってStatement.close保証されているため、明示的に ResultSet を閉じる必要はありません。だから書いていいよ

try (PreparedStatement stmt = con.prepareStatement(query)) {
    stmt.setString(1, name);
    ResultSet rs = stmt.executeQuery(query);
    ...
}
catch (SQLException e) {
    ...
}
于 2016-01-15T09:20:26.380 に答える
0

あなたはこれを好きにすることができます:

try (
     Connection con = em.unwrap(Connection.class);
     PreparedStatement ps = TryJumper.jump(con.prepareStatement("select * from x where a = ?"), pss -> {
         pss.setInt(1, 123);
     });
     ResultSet rs = ps.getResultSet();
) {
    //core codes
} catch (Exception e) {
    e.printStackTrace();
}

必要なクラス

public class TryJumper {

    public static <M> M jump(M m, MUser<M> mUser) throws Exception {
        mUser.consume(m);
        return m;
    }

    interface MUser<M> extends AutoCloseable {
        void consume(M m) throws Exception;

        @Override
        default void close() throws Exception {
        }
    }

}

どのように機能しますか:

try catch リソースでは、すべてがインターフェイスObjectからの実装を返す必要がありAutoClosableます。このクラスは、consume メソッドが動作した後に渡す同じオブジェクトを返すだけです (in lambda)

于 2021-06-17T15:42:29.373 に答える