2013-10-18 37 views
1

在下面的代碼,我通過executeRestitutionalQuery(String query)方法一個SQLite JDBC連接上執行的查詢:sqlite JDBC get on resultset總是返回null或者。 0

public static ArrayList<Metadata> findMetadata(String name, String text, String after, String before, String repPath) 
    throws SQLException, ClassNotFoundException { 

    ArrayList<Metadata> data = new ArrayList<Metadata>(); 
    boolean needADD = false; 

    String query = "SELECT * from " + TABLE_NAME_METADATA; 

    ... 

    query += " ORDER BY timestamp DESC;"; 

    ResultBundle bundle = executeRestitutionalQuery(query); 
    ResultSet result = bundle.getResultSet(); 

    while(result.next()){ 
     Metadata metadata = new Metadata(result.getLong("id"), result.getString("name"), Timestamp.valueOf(result.getString("timestamp")), 
       result.getInt("filesNo"), result.getLong("size"), result.getString("description"), -1); 
     data.add(metadata); 
    } 

    closeStatementAndResultSet(bundle.getStatement(), bundle.getResultSet()); 

    return data; 
} 

private static ResultBundle executeRestitutionalQuery(String query) throws SQLException, ClassNotFoundException{ 

    Connection connection = null; 
    Statement statement = null; 
    ResultSet result = null; 
    ResultBundle bundle = null; 

    try{ 
     connection = getConnection(); 
     statement = connection.createStatement(); 
     statement.executeUpdate(query); 
     connection.commit(); 

     result = statement.executeQuery(query); 

     bundle = new ResultBundle(statement, result); 

    }finally{ 

     if(connection != null){ 
      try{ 
       connection.close(); 
      }catch (Exception e){ 
       /* ignored */ 
      } 
     } 
    } 

    return bundle; 
} 
private static void closeStatementAndResultSet(Statement statement, ResultSet result){ 
    if(result != null){ 
     try{ 
      result.close(); 
     }catch (Exception e){ 
      // ignored 
     } 
    } 

    if(statement != null){ 
     try{ 
      statement.close(); 
     }catch (Exception e){ 
      // ignored 
     } 
    } 
} 

ResultBundle類只是用來總結結果集和該語句。它看起來像這樣:

public class ResultBundle { 

private final Statement statement; 
private final ResultSet result; 

public ResultBundle(Statement statement, ResultSet result){ 
    this.result = result; 
    this.statement = statement; 
} 

public Statement getStatement(){ 
    return statement; 
} 

public ResultSet getResultSet(){ 
    return result; 
} 

}

的問題是,每次調用result.getLong()result.getString()等返回null RESP。 0.我不明白爲什麼。查詢應該都可以,因爲代碼在我必須重構之前運行良好。 ResultBundle-class可以解決問題嗎?我在這裏沒有看到什麼?

回答

3

Statement s和ResultSet s是「活的」物體,只與其連接一樣長。 executeRestitutionalQuery返回ResultBundle,其0123¾和statement成員在finally塊中的連接關閉時返回時隱式關閉。

try { 

    ... 

}finally{ 

    if(connection != null){ 
     try{ 
      connection.close();  // <---- here's the problem 
     }catch (Exception e){ 
      /* ignored */ 
     } 
    } 
} 

到了時間,executeRestitutionalQuery調用者可以躺在它的手在資源包中,連接已關閉,結果集是「死」。

1

我會說這是一個糟糕的設計。

更好的方法是將SQL對象保持在緊湊的範圍內,將結果映射到集合或對象中並立即關閉所有稀缺資源。這些數據不僅可供客戶使用,還可以避免連接和遊標耗盡的問題。它的規模也會更好。