我在两个类中有两个静态方法:Account和FunnyDB。在FunnyDB中,我有一个方法,在Account中用于从数据库中检索对象。我想知道是否有可能以某种方式关闭来自Account方法的FunnyDB中的语句(stmt)。另外,如果真的不可能,那么离开陈述的结果是什么?这些是我的方法:
FunnyDB:
/**
* Returns ResultSet from query to get data to create object. Identufy data by id
*
* @param tableName Name of he table to search. Use getClass().getSimpleName().
* @param id
* @return
*/
public static ResultSet getObjectResultSetById(String tableName, int id) {
ResultSet rs = null;
try {
// gets object's details from database
Statement stmt = con.createStatement(); //<-- I WANT TO CLOSE THIS PARAMETER
String sql = "SELECT * \n"
+ "FROM " + tableName + " \n"
+ "WHERE " + tableName.toLowerCase() + "_id = " + id;
rs = stmt.executeQuery(sql);
//TODO: Closing rs and stmt? .close().
} catch (SQLException ex) {
Logger.getLogger(FunnyDB.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex.getMessage());
}
return rs;
}
帐户:
/**
* Returns object found by given ID.
*
* @param id Object ID.
* @return Object from database.
*/
public static Account getAccountFromDatabaseById(int id) {
Account account = null;
try {
ResultSet rs = FunnyDB.getObjectResultSetById("Account", id);
// create object to return
while (rs.next()) {
account = new Account(rs.getInt("account_id"), rs.getString("account_name"), rs.getString("account_type"), Currency.getCurrencyFromDatabaseById(rs.getInt("currency_id")), rs.getDouble("start_amount"), rs.getDouble("balance"));
}
rs.close();
//close stmt?????
} catch (SQLException ex) {
Logger.getLogger(Currency.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex.getMessage());
}
return account;
}
感谢您的帮助
答案 0 :(得分:3)
让一个类负责关闭与创建它的人不同的Statement
是一个坏主意。如果调用代码忘记关闭它会怎么样?
FunnyDB
班级应负责关闭Statement
;它创造了它。为此,它必须阅读ResultSet
本身,创建Account
,以便完全使用ResultSet
。这样,在ResultSet
和Statement
返回之前关闭它是没有问题的。
将创建Account
的代码移动到ResultSet
的{{1}}方法FunnyDB
。让该方法返回getObjectResultSetById
而不是Account
。关闭那里的ResultSet
和ResultSet
。您可能希望将其重命名为Statement
。如果您使用的是Java 7+,则可能还需要使用“try with resources”语句。您可以自动关闭getAccountById
和ResultSet
。如果您遇到Java 6或更低版本,请使用Statement
块来finally
,以确保在返回之前所有内容都已关闭。
close
中的getAccountFromDatabaseById
根本不需要操纵Account
;它只需要使用ResultSet
返回的Account
。
答案 1 :(得分:0)
您可以将ResultSet作为参数传递给getObjectResultSetById,因此getAccountFromDatabaseById可以将其关闭。
从不 EVER 保持资源畅通。在谈论数据库时,保持资源打开可能意味着在某个时刻你会得到一个“超出游标限制”或类似的东西,这很难调试。
此外,作为一般规则,请始终关闭finally
块中的资源。这样,即使您的方法抛出异常,也可以确保关闭资源。