2017-06-10 4 views
1

私はpreparedstatementを閉じた後に結果セットを得る方法はありますか? (Java)の

以下、このようなクエリを実行するための静的メソッドを作った(これはServerProcessクラスである)

public static ResultSet insertRow(Connection conn, String query){ 
    PreparedStatement pstmt = conn.prepareStatement(query); 
    ResultSet rs = pstmt.executeQuery(); 
    pstmt.close(); 
    return rs; 
} 

と&がここ

ResultSet rs = ServerProcess.insertRow(conn, query) 
    while(rs.next()){ 
    String nameOfEachOne = rs.getString("MEMBER_NAME"); 
    System.out.println(nameOfEachOne); 
} 
から結果セットを使用取得しよう

しかし、私が知る限り、ステートメント(またはpreparedstatement)が閉じられると、結果セットはノックオンの結果として閉じられるようになります。

何とかこの方法で使用したいと思いますが、どうやってそれを行うのか分かりません。声明文を閉じた後に情報を得る方法はありますか?

+1

準備が完了した後に結果セットを得る方法はありますか? (java)_いいえ –

+0

この[post](https://stackoverflow.com/questions/25493837/java-cant-use-resultset-after-connection-close)であなたの問題とその解決策についてより詳しく議論するとします。 –

+0

はい、私はそれが非感覚のように聞こえることを知っていますが、私はちょうど興味があり、良いアイディアがあるのだろうかと思っています。 – Guieen

答えて

1

いいえ。親PreparedStatementがすでに閉じられている場合は、ResultSetを受け取ることも、何も読み取らないこともできます。あなたは何ができるか

あなたはPreparedStatementを閉じる前に、ResultSetを読み込み、あなたが必要とするすべてのビジネス・オブジェクトを返す消費者と連携することである。

消費者インターフェース:

@FunctionalInterface 
public interface SQLConsumer<T extends ResultSet, E>// where E is going to be your Business-Object Type 
{ 
    E accept(T resultSet) throws IOException; 
} 

この方法は現在、どのようなパーサのリターンを返しますが、適切にすべてを閉じます。

public static <E> E insertRow(Connection conn, String query, SQLConsumer<? super ResultSet, ? extends E> parser) 
{ 
    E result; 

    // use the try-with-resources functionality 
    try (PreparedStatement pstmt = conn.prepareStatement(query) 
    ; ResultSet rs = pstmt.executeQuery()) 
    { 
     // give the ResultSet to the parser to process it before closing the PreparedStatement 
     result = parser.accept(rs); 
    } 

    return result; 
} 

し、その結果を解析する:

public void callingMethod() 
{ 
    ArrayList<String> result = insertRow(conn, "MY_QUERY", this::parseResultSet); 
} 

private ArrayList<String> parseResultSet(ResultSet resultSet) throws IOException 
{ 
    ArrayList<String> values = new ArrayList<>(); 
    while (resultSet.next()) 
    { 
     values.add(resultSet.getString("MEMBER_NAME")); 
    } 

    return values; 
} 
+1

を注意深く使用してください。多くのResultSet操作でSQLExceptionがスローされます。「Consumer 」は許可されません。 – Rogue

+0

はい、あなたの答えで見ました:p –

+0

ありがとうございます。私がConsumer Interfaceを見たのは初めてのことです。あなたの答えを使用して&参照するために、私はそれを勉強する必要がありました^^; – Guieen

1

理想的には、そのようなResultSetを公開することは決してありません。これは、非常に変更可能な/記述されたオブジェクトです。しかし、あなたはラムダ関数を経由してそれを使用することができ、それを提供し、まだそれを閉じたい場合は:もちろん

@FunctionalInterface interface SQLConsumer<T> { 
    public void accept(T t) throws SQLException; //default functional interfaces can't throw 
} 

public void query(String sql, SQLConsumer<? super ResultSet> action) { 
    ResultSet rs = /* various jdbc code */; 
    action.accept(rs); 
    rs.close(); //and other resources 
} 

//In usage: 
query("SELECT * FROM my_table", rs -> { 
    String s = rs.getString(1); //example 
}); 

を、あなたはこのような様々な方法を作成し、異なる間で個人的なプロジェクトのためにそのようなI've actually done abstraction自分自身をすることができますRDBMS。

+0

あなたの優しい答えをありがとう。 「ラムダ」という用語は難しいように見え、物理学と数学を思い出させる:)私は今日それを試してみよう! – Guieen

+0

ここでは、ラムダは基本的に(匿名クラスのような)「匿名メソッド」です。数学の定義と似ているのは、それが関数であることだけです(しかし、それは波長だから物理学ではありません) – Rogue

関連する問題