在以下代码中,我通过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
- 班吗?我在这里看不到什么?
答案 0 :(得分:4)
Statement
和ResultSet
s是“实时”对象,只有在连接时才能生存。 executeRestitutionalQuery
会返回ResultBundle
,当result
块中的连接关闭时,statement
和finally
成员会在返回时隐式关闭。
try {
...
}finally{
if(connection != null){
try{
connection.close(); // <---- here's the problem
}catch (Exception e){
/* ignored */
}
}
}
到那时,executeRestitutionalQuery
的调用者可以将手放在资源包上,连接已关闭,结果集已“死”。
答案 1 :(得分:2)
我会说这是一个糟糕的设计。
更好的方法是将SQL对象保持在狭窄的范围内,将结果映射到集合或对象中,并立即关闭所有这些稀缺资源。不仅数据可供客户端使用,而且还可以避免连接和游标耗尽的令人讨厌的问题。它也会更好地扩展。