java,如何关闭不同方法中使用的语句?
我在两个类中有两个静态方法:Account和FunnyDB。在FunnyDB中,我有一个在Account中用于从数据库检索对象的方法。我想知道是否有可能在FunnyDB from Account方法中以某种方式关闭语句(stmt)。此外,如果这真的不可能,不关闭声明会产生什么后果?以下是我的方法: FunnyDB:java,如何关闭不同方法中使用的语句?,java,sql,Java,Sql,我在两个类中有两个静态方法:Account和FunnyDB。在FunnyDB中,我有一个在Account中用于从数据库检索对象的方法。我想知道是否有可能在FunnyDB from Account方法中以某种方式关闭语句(stmt)。此外,如果这真的不可能,不关闭声明会产生什么后果?以下是我的方法: FunnyDB: /** * Returns ResultSet from query to get data to create object. Identufy data by id * *
/**
* 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;
}
感谢您的帮助您可以将结果集作为参数传递给getObjectResultSetById,以便getAccountFromDatabaseById可以关闭它 永远不要让资源处于打开状态。当谈到数据库时,让资源保持打开状态可能意味着在某个时刻您将得到“超出游标限制”或类似的结果,这很难调试
另外,作为一般规则,始终在
finally
块中关闭资源。这样,即使您的方法引发异常,您也可以确保资源将被关闭。让一个类负责关闭一条与创建它的语句不同的语句是一个坏主意。如果调用代码忘记关闭它怎么办
FunnyDB
类应该负责关闭语句
;它创造了它。为此,它必须读取结果集
本身,创建帐户
,以便完全使用结果集
。这样,在返回之前关闭结果集
和语句
就没有问题了
通过调用ResultSet
将创建帐户的代码移动到FunnyDB
的getObjectResultSetById
方法中。让该方法返回帐户
,而不是结果集
。关闭那里的结果集
和语句
。您可能需要重命名它getAccountById
。如果您使用的是Java 7+,您可能还需要使用“try with resources”语句。您可以自动关闭结果集
和语句
。如果您一直使用Java 6或更低版本,请使用finally
块关闭它们,以确保在返回之前所有内容都已关闭
Account
中的getAccountFromDatabaseById
根本不需要操作ResultSet
;它只需要使用FunnyDB
makestmt
返回的Account
作为类变量。必须在方法范围内关闭语句。你最好不要返回结果集。最好将其映射并在创建它的语句的相同方法范围内关闭。rs语句连接都应关闭,以便释放db连接。每次您与db建立连接时,即使您关闭应用程序,db也会保持连接打开。直到db的连接清理器启动。根据数据库服务器配置,打开连接有一个限制。一旦超过该限制,数据库将不会接受任何其他请求。唯一的解决方法是重新启动数据库。不同的数据库也会为每个连接分配一些内存。因此,更多打开的连接意味着您的数据库服务器将消耗更多内存。这是非常有用的解释,谢谢!我将尝试使用map。使用try with resources
是另一个选项,因为它将在任何实现它的对象上调用AutoCloseableclose()
方法。我完全同意。使用资源(来自java 7)尝试是一个更干净的选择。你的答案应该考虑好的实践,而不是你建议的解决方法。请参阅@rgetman answer以了解有关此问题的信息。因此,使用资源重试是否会关闭该语句?像这样的try(ResultSet rs=FunnyDB.getObjectResultSetById(“Account”,id)){/…}
我以前有过,但是我有几个不同的类,比如Accoun
,这就是为什么我想把这两个东西分开。无论如何,谢谢你*我以前有过,但是我有几个不同的类,比如Account
,这就是为什么我想把这两个东西分开,这样我就可以在每个不同的类中使用FunnyDB方法。无论如何,谢谢你!
/**
* 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;
}