SQLite JDBC get on resultset总是返回null resp。 0

时间:2013-10-18 20:36:36

标签: java sqlite jdbc

在以下代码中,我通过executeRestitutionalQuery(String query)方法对SQLite JDBC连接执行查询:

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。我无法理解为什么。查询应该都没问题,因为在我不得不进行一些重构之前代码运行正常。问题可能来自ResultBundle - 班吗?我在这里看不到什么?

2 个答案:

答案 0 :(得分:4)

StatementResultSet s是“实时”对象,只有在连接时才能生存。 executeRestitutionalQuery会返回ResultBundle,当result块中的连接关闭时,statementfinally成员会在返回时隐式关闭。

try {

    ...

}finally{

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

到那时,executeRestitutionalQuery的调用者可以将手放在资源包上,连接已关闭,结果集已“死”。

答案 1 :(得分:2)

我会说这是一个糟糕的设计。

更好的方法是将SQL对象保持在狭窄的范围内,将结果映射到集合或对象中,并立即关闭所有这些稀缺资源。不仅数据可供客户端使用,而且还可以避免连接和游标耗尽的令人讨厌的问题。它也会更好地扩展。