java,如何关闭不同方法中使用的语句?

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 * *

我在两个类中有两个静态方法:Account和FunnyDB。在FunnyDB中,我有一个在Account中用于从数据库检索对象的方法。我想知道是否有可能在FunnyDB from Account方法中以某种方式关闭语句(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;
}

感谢您的帮助

您可以将结果集作为参数传递给getObjectResultSetById,以便getAccountFromDatabaseById可以关闭它

永远不要让资源处于打开状态。当谈到数据库时,让资源保持打开状态可能意味着在某个时刻您将得到“超出游标限制”或类似的结果,这很难调试


另外,作为一般规则,始终在
finally
块中关闭资源。这样,即使您的方法引发异常,您也可以确保资源将被关闭。

让一个类负责关闭一条与创建它的语句不同的
语句是一个坏主意。如果调用代码忘记关闭它怎么办

FunnyDB
类应该负责关闭
语句
;它创造了它。为此,它必须读取
结果集
本身,创建
帐户
,以便完全使用
结果集
。这样,在返回之前关闭
结果集
语句
就没有问题了

通过调用
ResultSet
将创建
帐户的代码移动到
FunnyDB
getObjectResultSetById
方法中。让该方法返回
帐户
,而不是
结果集
。关闭那里的
结果集
语句
。您可能需要重命名它
getAccountById
。如果您使用的是Java 7+,您可能还需要使用“try with resources”语句。您可以自动关闭
结果集
语句
。如果您一直使用Java 6或更低版本,请使用
finally
关闭它们,以确保在返回之前所有内容都已关闭


Account
中的
getAccountFromDatabaseById
根本不需要操作
ResultSet
;它只需要使用
FunnyDB

make
stmt
返回的
Account
作为类变量。必须在方法范围内关闭语句。你最好不要返回结果集。最好将其映射并在创建它的语句的相同方法范围内关闭。rs语句连接都应关闭,以便释放db连接。每次您与db建立连接时,即使您关闭应用程序,db也会保持连接打开。直到db的连接清理器启动。根据数据库服务器配置,打开连接有一个限制。一旦超过该限制,数据库将不会接受任何其他请求。唯一的解决方法是重新启动数据库。不同的数据库也会为每个连接分配一些内存。因此,更多打开的连接意味着您的数据库服务器将消耗更多内存。这是非常有用的解释,谢谢!我将尝试使用map。使用
try with resources
是另一个选项,因为它将在任何实现它的对象上调用AutoCloseable
close()
方法。我完全同意。使用资源(来自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;
}