Выполнение двух Java PreparedStatements с одним соединением - выбор стиля - PullRequest
8 голосов
/ 27 июня 2011

Хорошо, я понял, что действительно задал слишком много вопросов, не внося свой вклад в сообщество, но я хочу узнать ваше мнение по этому поводу. Скажи, если у меня есть

private void closeAll(ResultSet rs, PreparedStatement ps, Connection con) {
    if (rs != null)
        try {
            rs.close();
        } catch (SQLException e) {
        }
    if (ps != null)
        try {
            ps.close();
        } catch (SQLException e) {
        }
    if (con != null)
        try {
            con.close();
        } catch (SQLException e) {
        }
}

и я хотел сделать несколько операций с моей базой данных MySQL, используя одно соединение. Лучше написать

Connection con = ...;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    ps = con.prepareStatement(...);
    rs = ps.executeQuery();
    if (rs.next()) ...;
} catch (SQLException e) {
    System.err.println("Error: " + e);
} finally {
    closeAll(rs, ps, null);
}
try {
    ps = con.prepareStatement(...);
    rs = ps.executeQuery();
    if (rs.next()) ...;
} catch (SQLException e) {
    System.err.println("Error: " + e);
} finally {
    closeAll(rs, ps, con);
}

или

Connection con = ...;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    ps = con.prepareStatement(...);
    rs = ps.executeQuery();
    if (rs.next()) ...;
    rs.close();
    ps.close();

    ps = con.prepareStatement(...);
    rs = ps.executeQuery();
    if (rs.next()) ...;
} catch (SQLException e) {
    System.err.println("Error: " + e);
} finally {
    closeAll(rs, ps, con);
}

Я считаю, что лучше иметь в виду либо более безопасный, более четкий, более краткий или более надежный. Я не уверен, будет ли последний всегда закрывать те подготовленные операторы и наборы результатов, которые открыты всякий раз, когда он встречает исключение, хотя я полагаю, что это выглядит более кратким. Но первый выглядит лучше, так как он более последовательный, но при этом увеличивает накладные расходы, поскольку использует больше блоков try finally.

Я понимаю, что часть автоматического управления ресурсами Java 7 Project Coin заставит меня склоняться к первому, поскольку ресурсы, используемые в заголовке, неявно являются окончательными в теле. Тем не менее, у меня есть достаточно времени, прежде чем мне придется беспокоиться о пересмотре своего кода, чтобы адаптировать его к ARM и иметь возможность удалить шаблонный код, поэтому остается вопрос: из двух вышеописанных стилей, что было бы лучше? Если они оба будут выполнять ожидаемое поведение, то даст ли последний заметный прирост производительности, извиняющий стиль «уродливее»?

Ответы [ 4 ]

6 голосов
/ 27 июня 2011

Мне кажется, это случай личных предпочтений. В свое время я написал код, который напоминает оба блока. Что касается производительности, я не думаю, что будет особенно заметная разница, скажут только тесты производительности.

Может случиться так, что разница в миллисекунду или около того, которую предоставляет одна версия, не вдвое менее важна, чем десять минут или около того, чтобы другой человек, читающий ваш код через шесть месяцев после того, как вы написали, потратил бы на вопрос, почему.

Мое личное предпочтение будет вторым. Вы говорите, что держите соединение открытым для базы данных. С первым блоком кода, если вы получите исключение, это будет обработано, но затем вы перейдете ко второй попытке / перехвату и попробуйте снова. Вы можете не захотеть этого, если первый не получится. Во втором случае исключение приведет к тому, что вы выйдете из кода, а затем закроете соединение.

Я программировал в основном на C #. Это было около восьми лет назад, когда я последний раз занимался какой-либо Java. Но я думаю, что есть и было много программистов на C #, которые обдумывали это. Во всяком случае, у меня есть.

4 голосов
/ 27 июня 2011

Если вы посмотрите на это, вы увидите, что логика несколько отличается - первая версия выполнит второй запрос, даже если первая обработка запроса не удастся. Вторая версия продолжит выполнение второго запроса, только если обработка первого запроса + результаты будут успешными.

1 голос
/ 27 июня 2011

2-й путь.Первый может не завершить соединение, когда возникает исключение в первом блоке try.Когда вы просто печатаете на stderr в блоке catch, тогда нет, но вы этого не сделаете.Или 2-е утверждение должно быть выполнено без учета успеха / неудачи первого?

0 голосов
/ 19 июля 2013

Я понимаю, что этот пост старый, но если вам повезло работать в среде Java7, я бы предложил использовать try-with-resource .

Он будет обрабатывать закрытие соединения для вас, поскольку новые версии класса реализуют интерфейс Closable .

public static void viewTable(Connection con) throws SQLException {

String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

try (Statement stmt = con.createStatement()) {
    ResultSet rs = stmt.executeQuery(query);

    while (rs.next()) {
        String coffeeName = rs.getString("COF_NAME");
        int supplierID = rs.getInt("SUP_ID");
        float price = rs.getFloat("PRICE");
        int sales = rs.getInt("SALES");
        int total = rs.getInt("TOTAL");

        System.out.println(coffeeName + ", " + supplierID + ", " + 
                           price + ", " + sales + ", " + total);
    }
} catch (SQLException e) {
    JDBCTutorialUtilities.printSQLException(e);
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...