Использование `java.sql.CallableStatement` много раз без его закрытия

#java #mysql #jdbc

#java #mysql #jdbc

Вопрос:

У меня есть java.sql.CallableStatement с 3 параметрами, и мне нужно вызывать его много раз, передавая разные значения для третьих параметров.

Как правильно это сделать? Я могу каждый раз создавать новый вызываемый оператор, но, насколько я понимаю, он будет обращаться к БД.

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

Он работает на соединении MySQL jdbc.

Фрагмент кода:

 CallableStatement pivot = connection.prepareCall("{CALL pivot(?, ?, ?)]");
pivot.setString(1, "a");
pivot.setString(2, "b");
while(someCondition) {
  pivot.setString(3, "c");
  ResultSet res = pivot.executeQuery();
  try {
    // ...
  } finally {
    res.close();
  }
}
  

Ответ №1:

таким образом, который у вас есть сейчас, вы экономите некоторые шаги при обработке вызова. Видите ли, каждый раз, когда вы готовите вызов new, он должен проходить в БД через оптимизатор, что требует времени и ресурсов. Как только ваш preparedCall настроен, оставьте его открытым (и сохраненным на сервере dbserver) для повышения производительности.

Вы пропускаете это в коде:

 if(pivot == null)
    pivot = connection.prepareCall("{CALL pivot(?, ?, ?)]"); 
  

вы должны сохранить pivot как поле вместо переменной.

Примечание: если вам нужны ресурсы, и у вас много PreparedStatements и вызовов, вам следует закрыть большие из них, которые вызываются не так часто.

Я нашел это в Microsoft: схема, как это работает отсюда. Я не мог найти лучшей картины этого.

Ответ №2:

Это нормально, если оператор открыт в течение длительного времени, если вы сами управляете подключением. Однако, вероятно, лучше делегировать эту работу тем, DataSource у которых есть пул подключений внутри (проверьте Apache DBCP, или ваш драйвер JDBC также может иметь конкретную реализацию); он будет делать то же самое, но, как правило, с меньшей вероятностью ошибки. И с источниками данных вы всегда должны закрывать оператор и соединение, чтобы вернуть их в пул.