Java 1.6 java.sql попробуй / поймай / наконец сумасшедшее кодирование - PullRequest
1 голос
/ 29 февраля 2012

В настоящее время я создаю множество классов, которые будут обращаться к базе данных с помощью пула соединений.Поэтому я получаю соединение, создаю заявление и получаю набор результатов.(Я не могу использовать Java 1.7 и фантастическое Автоматическое управление ресурсами ) Когда я заканчиваю свой метод, я должен закончить с блоком finally:

        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close result set", sqle);
            }
        }
        if (st != null) {
            try {
                st.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close statement", sqle);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close connection", sqle);
            }
        }

Я уже вижу кошмарный сонбудет для XX классов, имеющих по 4/5 методов.

Будет ли хорошей практикой создание вспомогательного класса, который получил бы специальный метод close для каждого типа объекта, например:

public static void closeResource(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException sqle) {
                logger.error("Couldn't close connection", sqle);
            }
        }

А потом просто делаю свой обычный finally с xx.close(connection);xx.close(statement);xx.close(rs);

Или с тем же мышлением (я знаю, что в этот момент я шокирую некоторых людей, так как я сам нахожу это немного странным), имея такой метод, какpublic static void closeResources(Object... obj) {} с ужасным списком instanceof?

Или, по вашему опыту, лучше все кодировать везде?

Ответы [ 4 ]

2 голосов
/ 29 февраля 2012

Использование проекта Apache commons: http://commons.apache.org/dbutils/apidocs/org/apache/commons/dbutils/DbUtils.html

DbUtils.closeQuietly () - это, вероятно, то, что вам нужно

2 голосов
/ 29 февраля 2012

Использовать перегрузку.

private void close(ResultSet rSet) throws SQLException {
    if (rSet != null) {
        rSet.close();
    }
}

private void close(Statement statement) throws SQLException {
    if (statement != null) {
        statement.close();
    }
}

private void close(Connection conn) throws SQLException {
    if (conn != null) {
        conn.close();
    }
}

Использование теперь станет намного чище:

try {
    // do db stuff
} catch (Exception e) {
    logger.error("log it", e);
} finally {
    close(rs);
    close(cs);
    close(conn);
}
1 голос
/ 29 февраля 2012

Еще один пример.Подходит для простых небольших проектов.

Object doRequest() throws SQLException {

    PreparedStatement ps = ... // initialize statement
    try {
        ResultSet rs = ps.executeQuery();
        try {

           // use ResultSet
           return someResult;

        } finally {
           rs.close();
        } 
    } finally {
        ps.close();
    }

}

Хотя это не претендует на полноту решения (многие вложенные try-finally совершенно не читаются), есть несколько преимуществ:Сам по себе не занимается обработкой исключений.Часто только вызывающая сторона может решить, что делать с исключением.

Как показано ниже, метод всегда возвращает правильный результат или выдает исключение.Никаких волшебных «значений ошибок» не требуется. Ресурсы закрываются, только если они были инициализированы.Не нужно проверять null Бероде close().
0 голосов
/ 29 февраля 2012

Вы также можете использовать тот факт, что для каждого класса, который вы хотите закрыть, метод close не имеет аргументов, и создать рефлексивный вспомогательный метод, подобный этому:

    public static final void tryClose(Object o){
        if(o != null){
            Method[] m = o.getClass().getMethods();
            for (Method method : m) {
                if("close".equals(method.getName())){
                    if(!method.isAccessible()) method.setAccessible(true);
                    try {
                        method.invoke(o);
                    } catch (Exception e) {
                        System.err.println(e);
                    }
                    break;
                }
            }
        }       
    }

РЕДАКТИРОВАТЬ: Протестировано с FileWriter, отлично работает на моем компьютере.

...