【问题标题】:SQLite JDBC get on resultset always returns null resp. 0SQLite JDBC 在结果集上总是返回空值。 0
【发布时间】:2013-10-18 20:36:36
【问题描述】:

在以下代码中,我通过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。 0. 我不明白为什么。查询应该没问题,因为在我不得不进行一些重构之前代码运行良好。问题可能来自ResultBundle-class 吗?我在这里没有看到什么?

【问题讨论】:

    标签: java sqlite jdbc


    【解决方案1】:

    Statements 和ResultSets 是“活”的对象,只要它们的连接就存在。 executeRestitutionalQuery 返回一个 ResultBundle,当在 finally 块中关闭连接时,其 resultstatement 成员在返回时隐式关闭。

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

    此时executeRestitutionalQuery的调用者可以下手资源包,连接已经关闭,结果集“死”了。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-04-12
        • 1970-01-01
        • 2015-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-15
        • 1970-01-01
        相关资源
        最近更新 更多