Повторное использование объекта подключения в одном методе - PullRequest
0 голосов
/ 12 сентября 2018

Я сталкивался с этим паттерном. Можно ли повторно использовать объект Connection в одном методе, когда для выполнения требуется несколько операторов SQL?

Моя первоначальная мысль - закрыть все ресурсы, прежде чем двигаться дальше:

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
    conn = ConnectionFactory.getConnection();
    ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
    ps.setString(1, "val");
    rs = ps.executeQuery();
    // get values used to determine the next statement type
} catch (SQLException e) {
    LOG.error("SQL failed.", e);
} finally {
    if(rs != null){rs.close();}
    if(ps != null){ps.close();}
    if(conn != null){conn.close();}
}
// Then another SQL statement is needed (either an UPDATE or INSERT).
// Repeat the same pattern to open, use and close the connection

Так же безопасно делать следующее? И если это безопасно, есть ли реальная выгода?

//... boilerplate
try {
    conn = ConnectionFactory.getConnection();
    ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?");
    ps.setString(1, "val");
    rs = ps.executeQuery();
    // ... more

    ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")
    // ... etc
} finally {
    if(rs != null){rs.close();}
    if(ps != null){ps.close();}
    if(conn != null){conn.close();}
}

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Повторное использование соединения не является анти-паттерном, оно вполне нормально.Повторное использование соединения является единственным способом выполнения обоих операторов в одной локальной транзакции JDBC.Если вы пишете приложения для доступа к реляционным базам данных, вам следует узнать о транзакциях.

Способ реализации обработки исключений подвержен ошибкам, поскольку, если при закрытии какого-либо ресурса возникает исключение, более поздние ресурсы не получаютзакрыто.Если закрытие подготовленного состояния выдает исключение, то соединение не закрывается.try-with-resources был бы улучшением, но способ, которым try-with-resources обрабатывает крайние случаи , заставляет меня избегать его для JDBC в пользу вложенных блоков try-finally.

Если здесь есть антипаттерн, он использует JDBC напрямую, он очень низкоуровневый, включает много операций вырезания и вставки и не позволяет легко использовать транзакции или пулы соединений.Использование Spring будет обрабатывать такие детали, как разграничение транзакций базы данных, использование пулов соединений и закрытие ресурсов для вас.

0 голосов
/ 12 сентября 2018

Что вы должны сделать, это использовать try-with-resources :

//... boilerplate
try (Connection conn = ConnectionFactory.getConnection()) {
    try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM MYTABLE WHERE COL=?")) {
        ps.setString(1, "val");
        try (ResultSet rs = ps.executeQuery()) {
            // ... more
        }
    }

    try (PreparedStatement ps = conn.prepareStatement("UPDATE MYTABLE SET COL=?")) {
        // ... etc
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...