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

时间:2015-02-17 18:39:03

标签: java sql

我在两个类中有两个静态方法: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;
}

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

让一个类负责关闭与创建它的人不同的Statement是一个坏主意。如果调用代码忘记关闭它会怎么样?

FunnyDB班级应负责关闭Statement;它创造了它。为此,它必须阅读ResultSet本身,创建Account,以便完全使用ResultSet。这样,在ResultSetStatement返回之前关闭它是没有问题的。

将创建Account的代码移动到ResultSet的{​​{1}}方法FunnyDB。让该方法返回getObjectResultSetById而不是Account。关闭那里的ResultSetResultSet。您可能希望将其重命名为Statement。如果您使用的是Java 7+,则可能还需要使用“try with resources”语句。您可以自动关闭getAccountByIdResultSet。如果您遇到Java 6或更低版本,请使用Statement块来finally,以确保在返回之前所有内容都已关闭。

close中的getAccountFromDatabaseById根本不需要操纵Account;它只需要使用ResultSet返回的Account

答案 1 :(得分:0)

您可以将ResultSet作为参数传递给getObjectResultSetById,因此getAccountFromDatabaseById可以将其关闭。

从不 EVER 保持资源畅通。在谈论数据库时,保持资源打开可能意味着在某个时刻你会得到一个“超出游标限制”或类似的东西,这很难调试。

此外,作为一般规则,请始终关闭finally块中的资源。这样,即使您的方法抛出异常,也可以确保关闭资源。