1. введение
Java Database Connectivity (JDBC) – это Java API, используемый для взаимодействия с базами данных. Пакетная обработка группирует несколько запросов в один блок и передает его в одном сетевом соединении в базу данных.
В этой статье мы узнаем, как JDBC можно использовать для пакетной обработки SQL – запросов.
Для получения дополнительной информации о JDBC вы можете ознакомиться с нашей вводной статьей здесь .
2. Зачем Нужна Пакетная Обработка?
Производительность и согласованность данных являются основными мотивами для выполнения пакетной обработки.
2.1. Повышение производительности
В некоторых случаях для использования требуется вставить большой объем данных в таблицу базы данных. При использовании JDBC одним из способов достижения этой цели без пакетной обработки является последовательное выполнение нескольких запросов.
Давайте рассмотрим пример последовательных запросов, отправляемых в базу данных:
statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) " + "VALUES ('1','EmployeeName1','Designation1')"); statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) " + "VALUES ('2','EmployeeName2','Designation2')");
Эти последовательные вызовы увеличат количество сетевых подключений к базе данных, что приведет к снижению производительности.
Используя пакетную обработку, эти запросы могут быть отправлены в базу данных за один вызов, что повышает производительность.
2.2. Согласованность Данных
В определенных обстоятельствах данные необходимо помещать в несколько таблиц. Это приводит к взаимосвязанной транзакции, в которой важна последовательность выдвигаемых запросов.
Любые ошибки, возникающие во время выполнения, должны привести к откату данных, переданных предыдущими запросами, если таковые имеются.
Давайте рассмотрим пример добавления данных в несколько таблиц:
statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) " + "VALUES ('1','EmployeeName1','Designation1')"); statement.execute("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) " + "VALUES ('10','1','Address')");
Типичная проблема в описанном выше подходе возникает, когда первое утверждение выполняется успешно, а второе-нет. В этой ситуации нет отката данных, вставленных первым оператором, что приводит к несоответствию данных.
Мы можем добиться согласованности данных, охватывая транзакцию несколькими вставками/обновлениями, а затем фиксируя транзакцию в конце или выполняя откат в случае исключений, но в этом случае мы по-прежнему повторно обращаемся к базе данных для каждого оператора.
3. Как Выполнить Пакетную Обработку
JDBC предоставляет два класса Statement и PreparedStatement для выполнения запросов к базе данных. Оба класса имеют свою собственную реализацию методов addBatch() и executeBatch () , которые предоставляют нам функциональность пакетной обработки.
3.1. Пакетная Обработка С Использованием Инструкции
В JDBC самый простой способ выполнения запросов к базе данных-это Оператор объект .
Сначала с помощью addBatch() мы можем добавить все SQL-запросы в пакет, а затем выполнить эти SQL-запросы с помощью executeBatch() .
Возвращаемый тип executeBatch() представляет собой массив int , указывающий, на сколько записей повлияло выполнение каждой инструкции SQL.
Давайте рассмотрим пример создания и выполнения пакета с помощью инструкции:
Statement statement = connection.createStatement(); statement.addBatch("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) " + "VALUES ('1','EmployeeName','Designation')"); statement.addBatch("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) " + "VALUES ('10','1','Address')"); statement.executeBatch();
В приведенном выше примере мы пытаемся вставить записи в таблицы EMPLOYEE и EMP_ADDRESS , используя Оператор . Мы можем видеть, как SQL-запросы добавляются в пакет для выполнения.
3.2. Пакетная Обработка С Использованием Подготовленной Информации
Подготовленный оператор – это еще один класс, используемый для выполнения SQL-запросов . Это позволяет повторно использовать инструкции SQL и требует, чтобы мы устанавливали новые параметры для каждого обновления/вставки.
Давайте рассмотрим пример с использованием PreparedStatement. Сначала мы настраиваем оператор, используя SQL-запрос, закодированный в виде строки :
String[] EMPLOYEES = new String[]{"Zuck","Mike","Larry","Musk","Steve"}; String[] DESIGNATIONS = new String[]{"CFO","CSO","CTO","CEO","CMO"}; String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) " + "VALUES (?,?,?)"; PreparedStatement employeeStmt = connection.prepareStatement(insertEmployeeSQL);
Затем мы перебираем массив значений String и добавляем в пакет недавно настроенный запрос.
Как только цикл будет завершен, мы выполним пакет:
for(int i = 0; i < EMPLOYEES.length; i++){ String employeeId = UUID.randomUUID().toString(); employeeStmt.setString(1,employeeId); employeeStmt.setString(2,EMPLOYEES[i]); employeeStmt.setString(3,DESIGNATIONS[i]); employeeStmt.addBatch(); } employeeStmt.executeBatch();
В примере, показанном выше, мы вставляем записи в таблицу СОТРУДНИК с помощью PreparedStatement. Мы можем видеть, как значения, которые должны быть вставлены, задаются в запросе, а затем добавляются в пакет, который будет выполнен.
4. Заключение
В этой статье мы рассмотрели, насколько важна пакетная обработка SQL-запросов при взаимодействии с базами данных с помощью JDBC.
Как всегда, код, связанный с этой статьей, можно найти на Github .