Что я должен закрыть первым, PreparedStatement или Connection?

При использовании PreparedStatement в JDBC следует сначала закрыть PreparedStatement или Connection? Я только что видел пример кода, в котором сначала закрывается Connection, но мне кажется более логичным сначала закрыть PreparedStatement.

Есть ли стандартный, общепринятый способ сделать это? Это имеет значение? Приводит ли закрытие Connection к закрытию PreparedStatement, поскольку PreparedStatement напрямую связано с объектом Connection?


person froadie    schedule 02.03.2010    source источник
comment
Хотя в соответствии со спецификацией оператор должен быть закрыт при закрытии соединения, у драйверов JDBC есть проблемы с этим, поэтому считается хорошей практикой явно закрывать оператор (и результирующий набор).   -  person Yishai    schedule 02.03.2010
comment
Закрывайте вещи в порядке, обратном тому, в котором вы их открывали. Все.   -  person user207421    schedule 02.05.2014


Ответы (2)


Заявление. Я ожидаю, что вы закроете (по порядку)

  1. набор результатов
  2. заявление
  3. связь

(и попутно проверяйте наличие нулей!)

т. е. закрыть в обратном порядке относительно открывающей последовательности.

Если вы используете Spring JdbcTemplate (или аналогичный), тогда он позаботится об этом за вас. В качестве альтернативы вы можете использовать Apache Commons DbUtils и DbUtils.close() или DbUtils.closeQuietly()< /а>.

person Brian Agnew    schedule 02.03.2010
comment
Верно. Некоторые драйверы JDBC выдают исключение при закрытии результирующего набора или оператора после закрытия соединения. - person Yishai; 02.03.2010
comment
Это правильно. К делу: закройте ресурсы в обратном порядке по мере их получения. - person BalusC; 02.03.2010

Необходимо выполнить следующие процедуры (по порядку)

  • ResultSet
  • PreparedStatement
  • Connection.

Кроме того, рекомендуется закрыть все объекты, связанные с JDBC, в finally close, чтобы гарантировать закрытие.

//Do the following when dealing with JDBC. This is how I've implemented my JDBC transactions through DAO....

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
  conn = ....
  ps = conn.prepareStatement(...);

  //Populate PreparedStatement
  rs = ps.executeQuery();

} catch (/*All relevant exceptions such as SQLException*/Exception e) {
  logger.error("Damn, stupid exception: " , e);
} finally {
if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                logger.error(e.getMessage(), e.fillInStackTrace());
            }
        }

        if (ps != null) {
            try {
                ps.close();
                ps = null;
            } catch (SQLException e) {
                logger.error(e.getMessage(), e.fillInStackTrace());
            }
        }

        try {
            if (conn!= null && !conn.isClosed()){
                if (!conn.getAutoCommit()) {
                    conn.commit();
                    conn.setAutoCommit(true);
                }
                conn.close();
                conn= null;
            }
        } catch (SQLException sqle) {
            logger.error(sqle.getMessage(), sqle.fillInStackTrace());
        }
}

Вы можете видеть, что я проверил, являются ли мои объекты нулевыми, и для соединения проверьте сначала, если соединение не установлено автоматически. Многие люди не проверяют это и понимают, что транзакция не была зафиксирована в БД.

person Buhake Sindi    schedule 02.03.2010
comment
Все это, в конце концов, должно быть сведено к служебному методу (например, DBUtils.close(rs, ps, conn);). Также совет по автокоммиту зависит от ситуации. Иногда, когда есть исключение, вы вообще не хотите совершать коммит. Кроме того, усилия по явной установке ссылки на null почти всегда не нужны, потому что она будет разыменована при выходе из метода, который, как мы надеемся, произойдет очень скоро после этого, иначе метод, вероятно, будет слишком длинным. - person Yishai; 02.03.2010
comment
@Yishai, да, я забыл упомянуть, что если есть исключения и автофиксация отключена, вы можете выполнить откат ... Спасибо, что показали это. - person Buhake Sindi; 03.03.2010